G - Prefix Concatenation Editorial by bayashiko


\(dp[i] =\) (相異なっても良い) \(S\) の接頭辞を \(k\) 個連結することで \(T\)\(1\) 文字目から \(i\) 文字目までを取り出した文字列 \(T'\) と一致させられるような最小の非負整数 \(k\)

とします。はじめ、

\( dp[i] =\left\{ \begin{array}{l} 0 & (i = 0) \\ ∞ & (i>0) \end{array} \right. \) です。

求めたいものは \(dp[|T|]\) です。

配るdpでこのdpテーブルを更新していくことを考えると、\(i\) の小さいほうから以下のように更新することが出来ます。

  • \(T\)\(i+1\) 文字目以降の \(l\) 文字と、 \(S\) の先頭からの \(l\) 文字が一致するような最大の非負整数 \(l\) を求める。
  • \(j=i+1,i+2,\ldots,i+l\) について、 \(dp[j]\)\(\min(dp[j],dp[i]+1)\) で更新する。

愚直に処理すると間に合わないので、高速に処理する方法を考えます。

前者の処理は例えばローリングハッシュを用いて二分探索を行うことにより \(O(\log \min(|S|,|T|))\) で行えるので、全体で \(O(|T| \log \min(|S|,|T|))\) で処理できます。
後者の処理は例えばSegment Tree Beatsの区間chminクエリで処理することによって全体で \(O(|T| \log |T|)\) で処理できます。(こちらはならし計算量です)

よって、入出力なども合わせた全体での計算量は \(O(|S|+|T| \log |T|)\) となり、実行時間制限に間に合わせることが出来ます。

posted:
last update: