公式解説が丁寧だけど、累積和の理解に時間がかかったのでメモしておく。
公式とは少し違うみたい。
距離D毎に射る。座標0付近を中心に左右にほぼ均等に割り振る。中心を0から距離Dより離す必要はない。
よって中心を0からDまで試せば良い。
(ここまで公式解説を参考に)
(実装上は左端を求めたほうが多分楽)
ここから最初に射る位置を として mod で分類して考える。
わかりやすいように、たまたま だったとする。
fig.1のような図を考える。
最初に射る位置を とすると、2射目以降 () の位置を射るので、Dで割ったあまりは常にpとなる。 よってp毎に全射の合計が求まれば、その最大値が答え。
そこでfig.2のようにD毎の範囲を移動してみると、連続する範囲(横向き)にスコアを足して、p毎に(縦向きに)合計を計算できれば、その最大値が求める答えになる。
これは、0,1,2...射目に得点の境界をまたぐなら、その範囲にスコアを足す累積和(imos法)で答えることが出来る(境界が無いなら全体にスコアを足す)。
縦向きの合計は、自然に求まるので、最大値を答えれば良い。
N回のループの中で、スコアの境界があったらimos法用の配列を2箇所更新するだけなので、十分間に合う(配列のサイズはD)。
(一射の中にスコアの境界が大量に存在する可能性があるけど、全体でスコアの境界は しかない)
(実装上は左端がp=0になるように全体の座標をスライドさせると楽)