鏂滅巼浼樺寲
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了鏂滅巼浼樺寲相关的知识,希望对你有一定的参考价值。
鏍囩锛?a href='http://www.mamicode.com/so/1/eve' title='eve'>eve closed cli 浜ょ偣 lld mutable end style amp
鍔熻兘:涓€涓竾鑳界殑鏂滅巼浼樺寲妯℃澘 鍙互瑙e喅妯潗鏍囦笉鍗曡皟 鏌ヨ鍧愭爣涓嶅崟璋冪殑闂
鏂滅巼浼樺寲闂瑙e喅鏂规硶:
鏂滅巼浼樺寲闂鏄綋dp寮忕被浼?dp_i = dp_j + a_i * b_j$褰㈠紡鏃舵棤娉曞乏鍙冲垎绂籭涓巎鏃剁殑涓€绉嶄紭鍖栧鏉傚害鐨勬柟娉曘€?br />
鎴戜滑閫氳繃鍙樻崲寰楀埌绫讳技$y = k * x + b$褰㈠紡,鍏朵腑$x$鍜?y$鏄彧鍏充簬$i$鐨勯」,$k$鍜?b$鏄彧鍏充簬$j$鐨勯」銆傚悓鏃?dp_i$鍦?y$涓?鎴戜滑甯屾湜閫夋嫨鍚堥€傜殑$k$涓?b$浣垮緱$y$鏈€澶ф垨鏈€灏?浠庤€屼娇dp[i]鏈€澶ф垨鏈€灏忋€?br />
浜庢槸鎴戜滑闇€瑕佺淮鎶や竴涓洿绾块泦鍚?(k,b)$,褰撻渶瑕?dp_i$鏈€澶ф椂鐩寸嚎闆嗗悎褰㈡垚涓嬪嚫鐨勫嚫鍖?鍙嶄箣鍒欏舰鎴愪笂鍑哥殑鍑稿寘,姣忔鏌ヨ$query(x)$鍗冲彲寰楀嚭缁撴灉,鍔犲叆鐩寸嚎鍒欐槸$add(k,b)$,澶嶆潅搴?O(nlogn)$銆?/p>
妯℃澘:
namespace struct Line mutable ll k, m, p; bool f; // 瀛樺湪鏂滅巼鍚?/span> Line() Line(ll _k, ll _m, ll _p, bool _f) : k(_k), m(_m), p(_p), f(_f) bool friend operator < (const Line &a, const Line &b) return (a.f && b.f) ? a.k < b.k : a.p < b.p; ; struct LineContainer : multiset<Line> // LineContainer() const ll inf = LLONG_MAX; ll div(ll a, ll b) //姹備氦鐐?/span> return a / b - (a ^ b < 0 && a % b); ld div(ld a, ld b) return a / b; bool Intersect(iterator x, iterator y) if(y == end()) x -> p = inf; return false; if(x -> k == y -> k) x -> p = x -> m > y -> m ? inf : -inf; else x -> p = div(y -> m - x -> m, x -> k - y -> k); return x -> p >= y -> p; void add(ll k, ll m) multiset<Line> :: iterator z = insert(Line(k, m, 0, 1)), y = z++, x = y; while(Intersect(y, z)) z = erase(z); if(x != begin() && Intersect(--x, y)) Intersect(x, y = erase(y)); while((y = x) != begin() && (--x) -> p >= y -> p) Intersect(x, erase(y)); ll query(ll x) // assert(!empty()); multiset<Line> :: iterator L = lower_bound(Line(0, 0, x, 0)); return L -> k * x + L -> m; ;
渚嬮:
Codeforces 631E
澶ф剰:浣垮緱$\sum_i=1^na_i*i$鏈€澶?鍙互灏嗕竴涓?a_i$鎻掑叆鍒颁换浣曚竴涓綅缃?br />棰樿В:闇€瑕佷袱娆?dp$,娌℃湁宸埆,浠呰鏄庣涓€閬?dp$銆?/p>
鏋氫妇浣嶇疆$i$,鑰冭檻绉诲埌浣嶇疆$j$鍓嶉潰涓?$j \leq i$銆?ans = max(tot + a_i*j-a_i*i+sum_i-1-sum_j-1)$銆傚寲鎴?y = k * x + b$褰㈠紡锛屽緱鍑?ans-tot-sum_i-1+a_i*i=a_i*j-sum_j-1$
鎵€浠?br />$k = j$
$b = -sum_j-1$
$x = a_i$
$y = ans - tot - sum_i-1 + a_i * i$
缁存姢涓嬪嚫澹筹紝鍏蜂綋瑙佷唬鐮併€傜瓟妗堝嵆鏄?query(a_i)+tot+sum_i-1-a_i*i$銆?/p>
#include <cstdio> #include <cstring> #include <algorithm> #include <set> #include <vector> using namespace std; typedef long long ll; typedef long double ld; namespace struct Line mutable ll k, m, p; bool f; // 瀛樺湪鏂滅巼鍚?/span> Line() Line(ll _k, ll _m, ll _p, bool _f) : k(_k), m(_m), p(_p), f(_f) bool friend operator < (const Line &a, const Line &b) return (a.f && b.f) ? a.k < b.k : a.p < b.p; ; struct LineContainer : multiset<Line> // LineContainer() const ll inf = LLONG_MAX; ll div(ll a, ll b) //姹備氦鐐?/span> return a / b - (a ^ b < 0 && a % b); ld div(ld a, ld b) return a / b; bool Intersect(iterator x, iterator y) if(y == end()) x -> p = inf; return false; if(x -> k == y -> k) x -> p = x -> m > y -> m ? inf : -inf; else x -> p = div(y -> m - x -> m, x -> k - y -> k); return x -> p >= y -> p; void add(ll k, ll m) multiset<Line> :: iterator z = insert(Line(k, m, 0, 1)), y = z++, x = y; while(Intersect(y, z)) z = erase(z); if(x != begin() && Intersect(--x, y)) Intersect(x, y = erase(y)); while((y = x) != begin() && (--x) -> p >= y -> p) Intersect(x, erase(y)); ll query(ll x) // assert(!empty()); multiset<Line> :: iterator L = lower_bound(Line(0, 0, x, 0)); return L -> k * x + L -> m; ; const int maxn = 5e5 + 5; int n; ll tot, ans; ll a[maxn], sum[maxn]; LineContainer H; int main() scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%lld", &a[i]); tot += a[i] * i; sum[i] = sum[i - 1] + a[i]; ans = tot; for(int i = 1; i <= n; ++i) if(!H.empty()) ans = max(ans, H.query(a[i]) + sum[i - 1] + tot - a[i] * i); H.add(1.0 * i, 1.0 * -sum[i - 1]); H.clear(); for(int i = n; i; --i) if(!H.empty()) ans = max(ans, H.query(a[i]) + sum[i] + tot - a[i] * i); H.add(1.0 * i, 1.0 * -sum[i]); printf("%lld\n", ans); return 0; /* 2 3 4 5 6 5 2 3 4 6 j = 2 i = 5 鍓嶅悗鍋氫袱閬? 鍓? 鍚戝墠绉籭绉诲埌j鍓嶉潰 ans = max(tot + a[i] * j - a[i] * i + (sum[i - 1] - sum[j - 1])) = max(tot + a[i] * j - sum[i - 1] - a[i] * i + sum[j - 1]) j <= i y = k * x + b y 鏈€澶? ans - tot - sum[i - 1] + a[i] * i = a[i] * j - sum[j - 1] x = a[i] y = ans - tot - sum[i - 1] + a[i] * i k = j b = -sum[j - 1] 缁存姢涓嬪嚫鍖? 鍚? 2 3 4 5 6 3 4 5 2 6 ans = max(tot + a[i] * j - a[i] * i + (sum[i] - sum[j])) */
以上是关于鏂滅巼浼樺寲的主要内容,如果未能解决你的问题,请参考以下文章