ABC207E Mod i
前に解説読んでよくわからなかったので寝かしていましたが、今回やってみたら解けました。
まず、以下に頻出の考え方について説明します。
ある整数列のを末尾とする連続した部分列の要素の和がの倍数となるような、全てのを求めることを考えます。
とすると、
の和はなので、
これがの倍数であるためには、
が成り立つ必要があり、したがって、
が成り立つようなは全て条件を満たします。
を1から順に探索し、その過程で、を記録しておけば、で、全てのを末尾とした数列について計算できます。
この考え方を前提とし、本題に移ります。
まず、一例として、問題の条件を満たすようなを末尾とした3分割の方法の総数を求めてみます。
これは前述した考え方を使うと、を満たすようなの全てで、連続した部分列の要素の和がの倍数となります。
そのため、を2分割するような分割の方法全てに対して、の部分列を付加し、3分割された数列を作り出すことができます。
そこで、以下のようなDPを考えます。
を末尾とした個に分割された数列であり、がであるものの総数
(個に分割された数列については、次のの余りを保存しなければいけないことに注意)
遷移は、各を末尾とする数列を個に分割する場合、
- を末尾とする数列が個に分割されていて、
かつ、
- としたとき、がであるもの
にを付加できる(との間で分割できる)ので、
+=
となります。
このままだと、状態数と計算量となります。
そこで、
個に分割された数列であり、「要素の和」がであるものの総数
とすると、総数は累積和的に計算できるようになり、末尾の情報も不要となります。
遷移は、
+=
状態数と計算量となります。
(但し、は分割の個数の多いほうから更新)
この遷移に基づいて、までの値を計算し、最後にを考慮したときに更新された分の和をとれば答えとなります。
提出コード:https://atcoder.jp/contests/abc207/submissions/25645338