K - Sum - |Max - Min|

2 secs 1024 MB
kusirakusira's icon kusirakusira

まず、min(B)\mathrm{min}(B)max(B)\mathrm{max}(B) が定まっているとき、min(B)\mathrm{min}(B) 以上で max(B)\mathrm{max}(B)以下の要素は選んだ方が得であるということが分かります。なぜなら、負の項max(B)min(B)|\mathrm{max}(B)-\mathrm{min}(B)|に変化なくプラスの項 sum(B)\mathrm{sum}(B) を大きくできるからです。

min(B)\mathrm{min}(B) を固定して考えます。(max(B)\mathrm{max}(B) を固定しても結果は同じですが、今回は最小値を固定する方針で考えます。)

まず、配列 AA を昇順にします。
区間の左端のインデックス ii を小さいほうから見ていき、ii 番目から何番目までの要素を選べばよいかを知りたいです。
仮に右端のインデックスを jj として、jjj+1j+1の差分を見てみます。
そうすると、右端をひとつ進めるごとに、max(B)\mathrm{max}(B) の値は大きくなりますが、sum(B)\mathrm{sum}(B) の増加分がそれを上回るため、右端を進めた方が得であるとわかります。
よって、各 ii 番目から NN 番目を選んだ時のスコアのうち、最大値が答えとなります。

区間和を累積和を用いて求めることで全体の計算量は O(N)\mathrm{O}(N) となります。

C++
Python