AC自动机 P1366
来说一下AC自动机.
大概就是给定一堆单词和一个很长的字符串,求字符串内这些单词出现的次数.如果只有两个字符串进行匹配可以写KMP,如果很多呢?我会字典树+KMP.
来复习KMP的核心思想:在A串中求B是否出现过,我们利用已经匹配好的B的后缀,当失配时尽可能的让指针在B上少向前跳.为此我们做出一个next数组表示失配时B上的指针应该跳到的位置.把这个思想放在字典树上,每个字典树上的节点都记录"当在这里失配时指针应该跳到的位置".
现在是否理解了呢?
来看例题吧.
当时是用暴力枚举O(m*maxlen)在字典树上跑了跑,甚至比AC自动机快2333(原文:https://www.cnblogs.com/qywyt/p/10256095.html).
现在考虑如何O(m+maxlen)的A掉?来看样例的几个单词.
假设你现在会写代码,对着这个图看一会,我们可以对这个字典树每个点都安上一个指针指向应该跳的位置.(默认深度大的指向深度小的)
应该怎么做呢?对于一个节点,它的失败指针要找自己父亲的失配指针所指的节点,如果有对应儿子就是它,否则继续向上跳失配指针,继续判断是否有对应儿子.
比如找sh的指针,它要看s的失配指针,发现指向了根节点,并且根节点有对应的儿子:h,于是sh的指针是h.
比如找she的指针,它要看sh的失配指针,发现指向了h,而且h有对应的儿子e,于是she的指针是he.
(这里对应的儿子指的是自己最后的那一个字母)
具体如何实现呢?
我会模拟!复杂度为O(n*maxlen*maxlen),有点菜.