$SAM$ + 倍增 + 线段树合并.
- 这里有两个小性质需要注意.
- 答案是可二分的.这个应该比较显然.
- 两个子串的最长公共后缀就是它们在 $SAM$ 上状态节点 $LCA$ 的 $maxlen$ .想象两个串都从前往后缩短,当两者缩到同一个串,即公共后缀时,节点也跳到了它们的 $LCA$ .长度即为 $maxlen$ .
- 于是把整个串翻转,询问前缀相关问题就变成了询问后缀相关问题.询问时,可以二分答案 $x$ ,转化为判定问题.
- 从 $d$ 对应的位置用倍增往上跳,找到 $maxlen\geq x$ 的 $dep$ 最小的祖先(其 $right$ 集合最大,为最优),判断它的 $right$ 集合中是否出现了 $[a+x-1,b]$ 中的某个位置.
- 如果出现了,那么从这个位置往前的 $x$ 个字符就是要找的子串,否则就找不到.
- 可以看出 $c$ 的作用就是限制了二分答案 $x$ 的范围,显然不能超过 $d-c+1$ 与 $b-a+1$ .
- 一个点的 $right$ 集合是它所有儿子节点 $right$ 集合的并集.所以可以用线段树合并来维护.
1 |
|