Australia

ウォンバットのブログ

AtCoder Regular Contest 100 F - Colorful Sequences

解法

「全ての列についての Aに一致する連続する部分列の個数の総和」から「カラフルでない列についての Aに一致する連続する部分列の個数の総和」を引く方針で考えます。前者は簡単なので省略します。後者は Aがカラフルな場合は 0なので、以下カラフルでないものとします。
まず次のDPを考えます。

 dp[i][j]=ある特定の長さ iのdistinctな列の後に、 j個の要素を繋げてできるカラフルな列の個数

次が成り立ちます。

 dp[i][j]=\displaystyle \frac {dp[i-1][j+1] - \displaystyle \sum_{i'=1}^{i-1} dp[i'][j]} {K-i+1}

ただし、このDPを初期化するには、 dp[1][j]が分かっていないといけません。そこで、

 dp'[j][k]=ある特定の 1項の後に、 j個の要素を繋げてできるカラフルな列であって、distinctなsuffixの最大長さが kであるものの数

というものを考えれば、

 dp'[j][k]=\displaystyle \sum_{k'=k}^{K-1} dp'[j-1][k']+(K-k+1)dp'[j-1][k-1]

と遷移が定義できることがわかります。 dp[1][j]=dp'[j+1][1]です。これらのDPはいずれも累積和で高速化できます。
さて、以上を使って「カラフルでない列についての Aに一致する連続する部分列の個数の総和」を求めていきましょう。
 Aがdistinctな場合。数列中に長さ Mのdistinctな列が登場する場合の数は、終了位置を jと固定すれば、 K \sum_{k=M}^{K-1} dp'[j-1][k]dp[k][N-j]です。その中に、 Aはちょうど \frac{(K-M)!}{K!}の割合で存在します。あとは j Mから Nまで動かして総和をとればよいです。
 Aがdistinctでない場合。 Aのdistinctなprefixの最大長さを l、suffixの最大長さを rとすると、数列中に Aが登場する場合の数は、開始位置を iと固定すれば、 dp[i-1][l]dp[N-M-i][r]になります。あとは i 1から N-Mまで動かして総和をとればよいです。
計算量は全体で O(NK)になります。

反省

5日かかりました。難しかった。
コンテスト中のACが少ない問題はなかなか解けなくても自己嫌悪に陥らないので良いです。(にしても5日はかかりすぎか)
 dpの遷移を立てるまでにかなりの苦労がありました。しかも蓋を開けてみたら非想定解でした。想定解の方が数倍賢い。