AC自动机算是kmp的升级版,第一次写这个,感觉很有收获
#include<stdio.h> #include<string> #include<map> #include<vector> #include<cmath> #include<stdlib.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; const int N=1e5+10; const int MOD=1e9+7; int n,m,k; char *str[N]; char *s[N]; struct node{ node *son[26]; int cnt; char ch; node *fail; node(){ init(); } void init(){ cnt=0; for(int i=0;i<26;i++) son[i]=NULL; fail=0; } }; node *root=new node(),*p,*tmp; void insert(char *s){ p=root; int i=0; while(s[i]){ int u=s[i]-'a'; if(p->son[u]!=0){ p=p->son[u]; }else{ tmp=new node(); p->son[u]=tmp; p=tmp; p->ch=s[i]; } i++; } p->cnt++; } node * q[2600000+1]; void init_fail(){ int l=0,r=-1; q[++r]=root; while(l<=r){ p=q[l++]; for(int i=0;i<26;i++) if(p->son[i]!=0){ if(p==root){ p->son[i]->fail=root; }else{ tmp=p->fail; while(tmp!=NULL){ if(tmp->son[i]!=0) break; else tmp=tmp->fail; } if(tmp!=NULL) { p->son[i]->fail=tmp->son[i]; } else { p->son[i]->fail=root; } } q[++r]=p->son[i]; } } } long long query(char *s){ p=root; long long res=0; int i=0; int len=strlen(s); for(int i=0;i<len;i++){ int u=s[i]-'a'; if(!p) p=root; while(p!=NULL && p->son[u]==0) p=p->fail; if(p==NULL) continue; p=p->son[u]; res+=p->cnt; tmp=p; while(tmp!=NULL){ tmp=tmp->fail; if(tmp==NULL) break; res+=tmp->cnt; } } return res; } int main(){ #ifndef ONLINE_JUDGE freopen("aaa","r",stdin); #endif int T; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); root->init(); root->fail=NULL; char st[N]; for(int i=0;i<n;i++){ scanf("%s",st); str[i]=(char*) malloc((strlen(st)+5)); strcpy(str[i],st); } for(int i=0;i<m;i++){ scanf("%s",st); s[i]=(char*) malloc((strlen(st)+5)); strcpy(s[i],st); insert(s[i]); } init_fail(); for(int i=0;i<n;i++) printf("%I64d\n",query(str[i])); } return 0; }