AC自动机的一点理解
\(fail\)指针:指向最长的在\(tire\)里出现的后缀
比\(tire\)多出来的子边:原来的\(tire\),我们失配后又得返回根结点再次匹配,而加入这些边后只需要花\(strlen(s)\)就能实现所有匹配
跑\(tire\)图:能跑到一个结点,该结点所代表的串能被文本串表示
例题
问题1:多个模式串,一个文本串,有几个模式串出现在文本串内
做法:对于多个模式串建自动机,文本串匹配,匹配到的点及\(fail\)点的代表的串都在文本串中
具体操作+优化:我们对于每个串的末端点\(val_i\)都记录代表几个串(建\(trie\)),在\(trie\)图中不变,然后每次匹配到的点往上爬并累加\(val\)值并标记,
之后再爬的时候到过标记了的点就退出,则保证了时间复杂度
问题2:多个模式串,一个文本串,求每个模式串出现的次数
做法:对于多个模式串建自动机,文本串匹配,匹配到的点及\(fail\)点的代表的串都在文本串中,并让这些串次数都+1
具体操作+优化:第一题我们用标记保证了时间复杂度,可这题需要得求每个串出现的次数,标记一下以后就找不到了怎么办?
先把文本串匹配一下,经过的点记录值,然后用topsort来处理,按相当于键fail树从叶子节点往上传,这样就能得到每个点代表的串出现的次数
最后再比较一下每个串的末节点出现的次数