存个自己写的AC自动机
1 #include<cstdio> 2 #include<cstring> 3 #define F(i,a,b) for(int i=a;i<=b;i++) 4 5 const int AC_N=10001*50,tyn=26;//数量乘串长,类型数量 6 struct AC_automation{ 7 int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot; 8 inline int getid(char x){return x-'a';} 9 void nw(){cnt[++tot]=0;memset(tr[tot],-1,sizeof(tr[tot]));} 10 void init(){tot=-1,fail[0]=-1,nw();} 11 void insert(char *s,int x=0){ 12 for(int len=strlen(s),i=0,w;i<len;x=tr[x][w],i++) 13 if(tr[x][w=getid(s[i])]==-1)nw(),tr[x][w]=tot; 14 cnt[x]++;//串尾标记 15 } 16 void build(int head=1,int tail=0){ 17 for(Q[++tail]=0;head<=tail;){ 18 for(int i=0,x=Q[head++],p=-1;i<tyn;i++)if(~tr[x][i]){ 19 if(x==0)fail[tr[0][i]]=0; 20 else for(p=fail[x],fail[tr[x][i]]=0;~p;p=fail[p]) 21 if(~tr[p][i]){fail[tr[x][i]]=tr[p][i];break;} 22 Q[++tail]=tr[x][i]; 23 } 24 } 25 } 26 int ask(char *s,int ans=0){ 27 for(int len=strlen(s),w,i=0,x=0,j;i<len;i++){ 28 while(tr[x][w=s[i]-'a']==-1&&x)x=fail[x]; 29 x=tr[x][w],x=(~x)?x:0,j=x;//加cnt后标记为0,防止重复计数 30 while(j&&cnt[j])ans+=cnt[j],cnt[j]=0,j=fail[j]; 31 } 32 return ans; 33 } 34 }AC; 35 char buf[1000010]; 36 int main(){ 37 int t,n; 38 scanf("%d",&t); 39 while(t--){ 40 scanf("%d",&n); 41 AC.init(); 42 F(i,1,n)scanf("%s",buf),AC.insert(buf); 43 AC.build(); 44 scanf("%s",buf); 45 printf("%d ",AC.ask(buf)); 46 } 47 return 0; 48 }