コンテストに参加してたら、数字が綺麗に並ぶ 2022/02/20 22:02:20 をうっかり見逃したので、ABC許さない(とばっちり)
i 0 1 2 3 4 5 6 7 C -2 -2 4 4 4 -3 -3 -3 B -2 -4 0 4 8 5 2 -1 A -2 -6 -6 -2 6 11 13 12 ~~~~ ←最大値
A の最大値を求める上では、Bi と比べて Bi+1 が正なら次も足した方がいいし、負ならそこでひとまず止めた方がいい。
よって、数列の長さは非常に長くなりうるが、最大値をチェックするのは B が正から負に切り替わるタイミング(と、最初と最後)だけでよい。
それがいつ切り替わるかを直接求めるのは難しいが、B における N 個の xi,yi の切り替わり点を追っていけばわかる。
j1 j2 j3 i 0 1 2 3 4 5 6 7 C -2 -2 4 4 4 -3 -3 -3 B -4 8 -1
切り替わり点の i を j1,j2,... と表す。
Bjk は、単に xk×yk を累積的に足していけば求められる。
Bjk と Bjk+1 を比べると、その中に A の最大値があり得るかどうかわかる。
正→負の区間だけチェックすればよいとわかった。
この中で切り替わる具体的な箇所 i を特定し、そこから最大値候補である Ai を求めたい。
切り替わり点から i が1つ進む毎に xk だけ減っていくので、Bjk−1−xk(切り捨て)だけ進んだ箇所が正、その次が負となる。
j1 j2 j3 i 0 1 2 3 4 5 6 7 C -2 -2 4 4 4 -3 -3 -3 B -4 8→ 5→ 2→-1 B[j2]/-x3 = 8/3 = 2 より、 i=4 から 2 進んだ i=6 がこの区間の中で最大を取る箇所
前の区間の終わり i=4 から d=2 進んだ箇所が最大値をとるとわかったので、A6 を求める。
先頭から累積的に計算することで、Aj1,Aj2,... は計算できる。
j1 j2 j3 i 0 1 2 3 4 5 6 7 C -2 -2 4 4 4 -3 -3 -3 B -4 8 -1 A -6 6 [] 12
1つ前の区間の終わりが Ar で、その次に C において n 個の xi が並んでいると、
と表現できる。
これを使うと、A6=A4+B4×d+d(d+1)2×x3=13 となり、正しく求められている。
正→負となる区間毎に調べていって、O(N) で全て求められる。
2次元なら、過去に類題があった(けどすっかり忘れてた)。
N 回ちょうどで (0,0) から (X,Y) に移動する。
操作回数が最低限の |X|+|Y| に足りなかったり、偶奇が合わない場合は最初に除く。
最低限から余る移動回数については、 無駄な移動(同じ軸の正方向と負方向の移動のセット)を k=\dfrac{N-(|X|+|Y|)}{2} 回、しなくちゃいけない。
素直に考えると、x 軸方向で何回、y 軸方向で何回行うか決めれば計算できる。 片方の無駄を 0~k に固定して場合分けすればよい。 しかし、これだと O(k) かかる。
テクニックとして、45度回転させ、(+1,+1),(+1,-1),(-1,+1),(-1,-1) の4つの移動で (X+Y,X-Y) に到達する、と問題を言い換えると、 2つの軸を独立に考えることができ、2つの二項係数の積で O(1) で計算できてしまう。