SAM + dfs 爆搜.
枚举 B 的子串左端点 $t$ ,即考虑所有是以 $t$ 开头的后缀的前缀.
$k$ 较小,可爆搜之,只要保证每次 $k$ 都在减少, dfs 的层数就是 $O(k)$ 的.
具体地,设状态 $(x,y,z)$ 表示串 $A$ 匹配到了位置 $x$ , 串 $B$ 匹配到了位置 $y$ ,还剩 $z$ 次修改机会.
若 $A_x=B_y$ ,则我们需要先跳过一段连续的可以匹配的段,这样接下来就一定会消耗一次修改机会.
在 SAM 上询问这两个位置的 LCP ,将其跳过即可.
若 $A_x\neq B_y$ ,则必须使用修改操作,可以将 $B_y$ 删掉,或在 $B$ 中加入一个 $A_x$ ,或将 $B_y$ 改成 $A_x$ .
这三种操作分别转移到 $(x,y+1,z-1),(x+1,y,z-1),(x+1,y+1,z-1)$ .
当某一个串匹配完成时,由于可能还剩下了若干修改操作,合法的前缀是一段区间,差分打上标记即可.
时间复杂度 $O(n\log n+n\cdot k^3)$ .
1 | //%std |