解説

dpテーブルを以下のように定義します。

  • dp[i][j]:=dp[i][j] := 長さ ii の文字列で、最後の jj 文字が、 TT の最初の jj 文字と一致しているものの個数

ただし、jj はできるだけ大きい値をとるようにする必要があります。

例えば、 T=0101T=0101 のとき、文字列 1010110101 の最後の 22 文字と TT の最初の 22 文字が一致しているとも考えられますが、
最後の 44 文字が TT の最初の 44 文字と一致していると考えます。

遷移は以下のようになります。

  • dp[i+1][j+1]+=dp[i][j]dp[i+1][j+1] += dp[i][j] (Si+1=Tj+1)(S_{i+1}=T_{j+1})
  • dp[i+1][p[j+1]]+=dp[i][j]dp[i+1][p[j+1]] += dp[i][j] (Si+1Tj+1)(S_{i+1} \neq T_{j+1})

ここで、 p[j]p[j]T1T2...Tk1=Tjk+1Tjk+2...Tj1T_1T_2...T_{k-1}=T_{j-k+1}T_{j-k+2}...T_{j-1} かつ TkTjT_k \neq T_j を満たす最大の kk です。
配列ppO(T2)O(|T|^2) で前計算した上で、dpテーブルの更新は O(NT)O(N|T|) で行うことができます。