1. 程式人生 > 其它 >【補題】Seg 貪心+均攤+性質+妙妙題

【補題】Seg 貪心+均攤+性質+妙妙題

題意

給定序列 \(A\) , 定義 \(f(A)\) 為序列 \(A\) 的最大非空子段和。
你可以花費 \(1\) 的代價,令 \(A\) 中某個元素 \(a_i\) 減一。
\(g(i)\) 的值為花費了 \(i\) 的代價後最小的 \(f(A')\)
\(\sum _{i=1} ^K g(i)\)
其中 \(1 \leq n \leq 2 \times 10^{5},-10^{8} \leq a_{i} \leq 10^{8}, 1 \leq K \leq 10^{13}\)

做法

考慮如何求出單個 \(g(k)\)
考慮二分答案。
\(S\)\(A\) 的字首和陣列,目前列舉的答案為 \(w\)

。接下來就是如何判定。
花費代價可以轉化成 \(S\) 字尾減一,則現在就是判定是否存在一種方案使得 \(\forall i<j,a_j-a_i\leq w\)

考慮從前往後貪心。設 \(lim\) 為後面的數不能超過的閾值。
\(lim \leq a_i\),則進行 \(a_i-lim\) 次操作,然後令 \(lim=min(lim,a_i+w)\)
其實不必顯式計算出 \(lim\) 的值,直接令 \(lim=a_i\) 即可。(因為花費代價的操作為字尾減)
上述貪心不難證明。

我們發現,隨著 \(k\) 的增大,原函式 \(g\) 的減小將越來越難。且使 \(g(i)\)

減少 \(1\) 的代價最多不超過 \(n\)
一個極端的情況是,若全部的 \(a_i\) 均為同一負數,則減小 \(1\) 的代價即為 \(O(n)\) 的。
因此二分出代價區間即可。
時間複雜度 \(O(n^2logw)\)

這還是太慢了...考慮去除冗餘計算,我們的 \(lim\) 重複計算太多次了。

考慮如何一次計算對於 \(w\) 的代價。操作僅有兩種
\(A(w):=A(w)+\max \left(0, a_{i}-L(w)\right), L(w):=\max \left(a_{i}, L(w)\right); \\ L(w):=\min \left(L(w), w+a_{i}\right)\)


然後大力維護即可