Official

D - DRD String Editorial by Mitsubachi

別解

$O(N \log N)$ 解法を説明します。前準備として $M^0, M^1, \dots, M^N$ を列挙しておきます。
$\mathrm{dp}_i$ を長さ $i$ の文字列で、 $R$ が空文字列でも良いとした場合の DRD文字列 でないものの個数とすると、答えは $\sum_i \mathrm{dp}_i \times M^{N - 2i}$ です。

$\mathrm{dp}$ は以下のような疑似コードで求められます。

for i in range(1, N):
    dp[i] += pow(M, i)
    for j in range(2 * i, N):
        dp[j] -= dp[i] * pow(M, j - 2 * i)
これは $O(N^2)$ で動作するので、高速化を考えます。

$\mathrm{dp}_{1}, \mathrm{dp}_{2}, \dots, \mathrm{dp}_{2^d}$ まで求まっているとします。このとき、 $\mathrm{dp}_{2^d+1}, \mathrm{dp}_{2^d+2}, \dots, \mathrm{dp}_{2^{d+1}}$ について、上の疑似コードの $4$ 行目で引かれる部分の合計は以下のように求められます。
配列 $A = (\mathrm{dp}_{1}, 0, \mathrm{dp}_{2}, 0, \dots, \mathrm{dp}_{2^d} ), B = (M^0, M^1, \dots, M^{2^{d+1}-2} )$ を用意します。 $A$ と $B$ を畳み込んだ配列の (1-indexed で) $x$ 番目について、その値が上の疑似コードの $4$ 行目で $\mathrm{dp}_{x+1}$ から引かれる部分の合計です。これは $O(2^d \log 2^d)$ で動作します。

よって全体で \(O(N \log N)\)\(\mathrm{dp}_i\) の列挙ができます。これより \(O(N \log N)\) で解けました。

posted:
last update: