算法复键——AC自动机
算法复键——AC自动机
本文搬运自本人高中时期CSDN博客,若图片加载不出来,可到原文查看:https://blog.csdn.net/zhangtingxiqwq/article/details/162074359
什么是AC自动机:
在Trie上跑kmp
核心思想:构建fail树。fail[u]指向一个节点,表示这个节点具有和u所在节点所代表串的最长公共后缀。
核心代码:
1 | void bfs() { |
-
初始化根
根节点u=1入队,fail[1]=0;虚拟节点0的fail[0]=1,防止无限回跳。 -
取出队首节点
u,遍历26个字母,找到真实存在的子节点v=ch[u][i] -
求
fail[v](KMP核心逻辑)
-
k = fail[u]:跳到u的最长后缀节点 -
如果
ch[k][i]存在,说明这个后缀节点有相同字母子节点,fail[v]=ch[k][i] -
不存在则回退到根1,
fail[v]=1
等价KMP:匹配失败时,找最长相等前后缀起点
- 路径压缩(重要优化)
1 | if(!ch[v][j]) ch[v][j] = ch[fail[v]][j]; |
正常AC不压缩:匹配时要循环跳fail找子节点;
你这里预处理填满所有 ch[v][j] ,之后 run 遍历文本时 不需要回跳fail ,直接 ch[u][c] 一步到位,省去循环,速度更快。
5. 建fail树 G : G[fail[v]].push_back(v) ,把所有后缀关系存成树,用于后序统计。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 zhangxixi的博客!




