問題文


https://atcoder.jp/contests/abc329/tasks/abc329_e

解法


操作を逆順に考える。

image.png

文字列 $S$ から貪欲に $T$ の文字列を取り除く操作を行い続けて最終的に $S$ が # だけになったら Yes ということである。

問題文通り $|S|=N~,|T|=M$ とする。indexは 0-indexed で考える。

この操作をナイーブに行うと $\mathcal{O}(N^2)$ かかってしまう。

取り除く操作を添字 $i$ を始点として $s[i,i+m)$ の半開区間を # にするものと定義する。

操作を一回だけ行うことを考えると、操作後新しく取り除ける可能性のある始点の範囲は $[i+1 ,i+m-1]$ と $[i-m+1,i-1]$ の閉区間である。

この範囲さえ調べれば新しく取り除ける文字列を探せる。

$M$ は十分小さいため $(M\leq \mathrm{min}(N,5))$ 計算量としては問題ない。

あとは順番通りに操作する必要があるため、始点を探して queue で実装する。

また同じ始点を再探索する可能性があるのでbool配列等で管理しておくと実装しやすい。

計算量 $\mathcal{O}(NM^2)$