具体讲解看OI-wiki就好了
构建字典图的那个位置,只用理解路径压缩就好了;在路径压缩完了之后,tr[u][i]
表示的是状态\(u\)接上一个字符\(i\)所表示的字符串能够与\(Q\)所匹配的最大后缀长度。形式化地,设\(s=u+i\),令\(P\)为\(s\)的后缀集合,tr[u][i]
=\(\max(|p|)\),其中\(p∈P\)且存在\(v∈Q\)使得\(p=v\);这部分代码的时间复杂度显然是\(O(n|\sum|)\),其中\(n\)为AC自动机的节点数目,\(\sum\)为字符集
对于匹配部分的代码,\(u\)代表的是\(Q\)的一个状态,且\(u\)为文本串的以第\(i\)个字符结尾的后缀与\(Q\)匹配的能达到最大长度的位置(结合我们上面的tr[u][i]
讲解,不难发现代码的维护可以让\(u\)有这一点性质),当前只用统计文本串的以第\(i\)个字符结尾的后缀与所有模式串的匹配情况(因为以\(1\) ~ \(i-1\)结尾的后缀在之前被统计过了),由于\(u\)表示的是最大长度,所以只用从\(u\)开始一直跳fail
指针就好了;而由于出现一个模式串出现了多次只用统计一次,所以可以让e[j]=-1
,并且当e[j]==-1
时就停止循环,因为在之前已经统计过了;这一部分的时间复杂度为\(O(|T|+n)\),因为AC自动机上每个节点最多被遍历一次
效率优化那两块还没学,有时间了学一下
标签:AC,匹配,后缀,tr,只用,简单,自动机 From: https://www.cnblogs.com/dingxingdi/p/18360165