标签:扩展 问题 接下来 模式 结束 lin 线段 串匹配 答案
AC自动机
这两天进军AC自动机算法,越做越觉得这种算法的灵活与高效,接下来对这阵子的学习做个总结。
AC自动机,当然它最主要的作用是自动帮你AC题目多模式串的匹配,也就是字典树trie和kmp的结合,再深入讲就是把kmp中失配时跳转的思想运用到trie上!
1.AC自动机构建
对于构建,基本上都是模板,先建trie,再BFS这颗trie从而构建出最重要的fail指针,即失配跳转指针(口头表达),fail指针指向的是当前状态的最长后继。
而一般我们为了加快速度,每个节点还会构建类似虚节点的东东,说清楚点就是把这个节点不存在的儿子指针指向它最长后继(即fail指向的那个节点)的该儿子,这样做可以在结束该串匹配时快速跳转到另一条模式串上继续匹配,具体自己脑补或者看代码吧(作者比较懒)。
2.AC自动机的扩展点
一般我们在失配时,会跳转fail指针继续匹配,我们把这个叫暴跳!!
暴跳,顾名思义,很费时间,所以一般会被题目卡掉,这样的话,我们一般就考虑fail树,即fail边所连成的树。为什么保证是树?因为显然每个节点只有一个父亲。
这样建好fail树后,每个节点的子树中所有节点表示的状态肯定包含该节点状态所表示的字符串,所以若要统计某一模式串在要求串中共出现的次数,只需要把要求串的所有节点权值加一,然后答案就是模式串的末节点子树大小。
统计子树大小的问题值得深究,因为很多题目中模式串和要求串都不止一个,即树上的权值肯定要变,若用遍历统计子树大小的方法来计算不优秀,这时我们采用DFS序来把树转化为线段区间问题,这样我们就可以用树状数组维护。具体来讲就是记录每个节点的dfn和low值,放在线段上看,dfn和low中间的区间,就是它的整个子树,这样就很好解释为什么可以用树状数组了吧。
标签:扩展 问题 接下来 模式 结束 lin 线段 串匹配 答案
原文地址:https://www.cnblogs.com/yzxx/p/11256934.html