No.752 mod数列
問題
数列
が与えられる。
個のクエリ
に対して
を求めよ。
制約
解法
まずおなじみの累積和テクニックの考え方から
が成り立つので、任意のに対して
を求めるにはどうすればよいか?を考えることにします。
ここで程度までであれば単純に累積和でやればいいんですが、今回は
ですので一筋縄ではいかなさそうです。まずいきなり和を考えるのではなくて、数列
がどのようになっているかを考えてみることにします。自明ではあるが重要なこととして、
となっていることが分かります。よって
だけで考えてみることにします。
こういうのは小さな具体例から考えてみるとよいので、として
がどのようになるかを見てみます。
i | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
0 | 0 | 0 | 0 | 4 | 0 | 3 | 0 | 6 | 4 | 2 | 0 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
すると一つ分かりやすい法則が見えます。となるにしたがって
は一つずつ減っていくことが分かります。このことを式で表すと
となるということが分かります。さらに
にも着目するとここでも規則性が見えて、
が2ずつ減っていくことが見て取れます。これも式で表すと
となることが分かります。
ここまで分かると一般化することが出来て、最初の自明な事実も合わせると、
任意のに対して
と表せることが分かります。ここでのとき
と考えることにするとつじつまが合います。
そしてこれが分かると、を固定したときの区間
に含まれる
に関する
の総和というのは簡単に分かります。
は単に区間の長さ倍すればよく
の部分はおなじみの
という公式を使えばよいからです。
さて、この事実が分かると何がよいのでしょうか?
任意のに対して
で、この区間に対して
の和は
で求められます。なので
と回せばいいわけですが、
までなのでこれでは計算量の削減になっていません。
しかし、までやるとしてみましょう。すると
の部分に対してはこれで求められて、残りの
の部分は累積和で求めてやることにすると計算量が良い感じに収まることが分かります。
後は和の上限が指定したを超えないように適宜区切ったりなんやかんやする必要がありますが、大筋のアイデアはこんな感じで計算量は今回は適当に
とかにしましたが一般には
くらいにするのがいいので
に出来ます。
感想
計算量にルートが出てくる問題ってあまり無い気がして面白かったので久々に書きました。