Longest Common Substring
\[ Time Limit: 294ms \quad Memory Limit: 1572864 kB \]
题意
给出两个串,求两个串的最长公共连续子序列的长度,两个串的长度小于等于250000。
思路
先对第一个串构建后缀自动机,根据后缀自动机的性质,从 \(root\) 的所有路径都是原串中的子串,又因为构建的时候,我们用 \(node[i].len\) 表示与节点 \(i\) 的 \(endpos\) 相同的所有子串集合的最长长度,那么我们就可以在后缀自动机上一次添加一个字符的去查询 \(res\) ,然后最大的 \(res\) 就是最后的答案。
在后缀自动机上查询的时候,我们用两个变量来更新答案,
\(p\) 表示现在在后缀自动机上的状态,
\(res\) 表示目前的最长公共连续长度。
- 如果对于下一个字符 \(k\) ,现在的 \(p\) 有这样的一条边,那么直接更新 \(p\),并且 \(res\)++。
- 如果没有这样的一条边,那么就从 \(p\) 跳到 \(node[i].fa\) 的位置,一直跳到有 \(k\) 的一条边为止停下或者走完整个后缀自动机。
- 如果跳到结束也没有找到 \(k\) 边,那么就让 \(p\) 变回 \(root\),\(res=0\)。
#include