Codeforces Round #523 C - Multiplicity
問題概要
数列が与えられ、数列から0個以上の要素を取り除いた数列を数列という。
数列の要素が1つ以上あり各が で割り切れる時、数列を数列の良い部分列と呼ぶ。
数列の良い部分列の総数を109+7で割った余りを求める。
制約
1 105
1 106
考えたこと
解説ACをしたのでこれCodeforces Round #523 Editorial - Codeforcesと同じことをしました。
まず、「:= まで見たときに個で構成される良い部分列の数」というDPを考える。 遷移は以下のようになり、が答えになるが制約的に二次元配列ではもてない。
$$ dp[ i ][ j ]= \left\{ \begin{array}{} dp[ i-1 ][ j ] + dp[ i-1 ][ j-1 ] & ( a_i が j で割り切れる時) \\ dp[ i-1 ][ j ] & (上以外の時) \end{array} \right. $$
Editorialにははにのみ依存するから1次元でもうまくいくよ!みたいに書いてあったがこれでは納得ができなかった。
参加者のコメントを参考に考えた結果、
「:= 個で構成される良い部分列の数」というDPを考えるとする。
例えばの時、の約数はなのでは数列の1番目、2番目、3番目、6番目に置くことができるのはわかる。
なのでの約数を降順にのように更新していけばいいことになる。
昇順に更新していった場合、の例で言えば1番目にを使ったのに2番目でもを使うといったことが起きてしまうため正しくないことがわかる。
からまでのに対して順に上の操作を行い、適宜109+7でmodをとればが答えになる。
提出コード:Submission #46102628 - Codeforces