后缀自动机
后缀自动机的疑难点
代码
void sam_extend(char c) {
int cur = sz++;
st[cur].len = st[last].len + 1;
int p = last;
while (p != -1 && !st[p].next.count(c)) {
st[p].next[c] = cur;
p = st[p].link;
}
if (p == -1) {
st[cur].link = 0;
} else {
int q = st[p].next[c];
if (st[p].len + 1 == st[q].len) {
st[cur].link = q;
} else {
int clone = sz++;
st[clone].len = st[p].len + 1;
st[clone].next = st[q].next;
st[clone].link = st[q].link;
while (p != -1 && st[p].next[c] == q) {
st[p].next[c] = clone;
p = st[p].link;
}
st[q].link = st[cur].link = clone;
}
}
last = cur;
}
构造后缀自动机
- 从后缀链接树的
状态向上跳,会遍历到长度为 的所有区间,即这个字符串的所有后缀,若跳到了根节点也没有 的转移,那么就是整个 中不存在字符 ,那么为 的每一个 转移都指向新加入的那个点,后缀链接树上,将 的后缀链接指向根节点,这是独一无二的
-
后缀链接树向上找,找到的每个状态都是
的后缀,如果这个状态 通过转移 正好能够走到 ,并且 是它所属的 等价类中最长的,那么显然 不会在前方相比 突出一块,会与 对齐,而 是 的后缀, 即 必然是 的后缀,所以 的 必然是 的一个真子集,而由于我们找的是顺着后缀链接树的第一个满足条件的 ,它必然是最长的,又由于 也是它对应的 等价类中最长的,所以 不断地删头 首次发生变化必然是删到 时,所以直接相连是没有问题的 -
为什么找到一个
就停下来?因为如果我们继续向上跳,跳到的必然是 的后缀,记为 ,所以它通过转移 对应的状态 也一定是 的后缀,那在后缀链接树上, 一定是 的父亲,由于后缀链接树上,儿子的 集合是父亲的真子集,所以在 的儿子接上位置 之后,由定义,它的所有的父节点的 集合都顺水推舟、水到渠成的拥有了位置 ,所以只连一次就符合了 的定义
-
我们发现,不同于上一个情况,我们的
状态的前端和 状态相比突出了一块,而这时候我们找到的 的最大的 集合不同的后缀是 而不是 ,因此增加 之后,仅仅有 的状态的 集合增加了 ,我们记这个状态为 ,可以发现它实际上是 状态中最短的子串,所以合着 状态中只有最小的 的 增加了。怎么办呢?我们考虑将q状态拆开,将到 的转移 全部指向 ,与此同时, 的所有转移, 也一定继承。这很好理解,因为 实际就是 的后缀,在它后面加什么 ,所指向状态的 都不会受影响, 与 还是一家人(一家人再怎么打骂起分歧也不会分开),所以这么连肯定也是对的 -
下面考虑后缀链接树怎么搞,首先一个显而易见的结论,
的 集合仅仅只比 的 集合多了一个元素 ,这里好办,让 代替 的位置,然后把 和 的后缀链接指向 (为什么能取代,儿子取代父亲的位置不是恒河里吗doge),然后我们通过后缀链接树向上跳,如果发现 ,那么就在 上把这个 的转移 直接连到 上("将到 的转移 全部指向 ",对应的就是上文的这句话),因为这时跳到的 的 集合包含 ,它显然不应该指向 。如果发现 ,这句话是什么意思呢?就是我们的 已经足够小了,此时跳到的 是起初 的后缀,再增加一个字符 会形成一个更大的 集合,增加字符后形成的 显然也是 的后缀,接着向上跳形成的 也同样是 的后缀。所以我们发现,再往上走都是 的祖先,而由于 的存在,上面所有的状态的 显然都包含有 ,这时 再向 连边就没有一个状态两种 集合的情况了,所以它是对的
复杂度证明
-
空间复杂度显然正确,因为每一次插入字符时,
的状态数只会增加两个,因此为 ,上界为2n-1,在形如字符串 时取到,这就是为什么 的空间要开两倍 -
时间复杂度,分两种情况讨论
posted on 2023-01-30 21:12 star_road_xyz 阅读(92) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效