字符串:AC自动机
给出一个字典和一个模式串,问模式串中出现几个字典中的单词
最后一行是大串,之前输入的是小串
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 char s[51],m[1000001]; 5 int T,n,sz,ans; 6 int a[500001][27],q[500001],point[500001],danger[500001]; 7 bool mark[500001]; 8 void ins() 9 { 10 int now=1,l=strlen(s); 11 for(int i=0;i<l;i++) 12 { 13 int t=s[i]-'a'+1; 14 if(a[now][t])now=a[now][t]; 15 else now=a[now][t]=++sz; 16 } 17 danger[now]++; 18 } 19 void acmach() 20 { 21 int t=0,w=1,now; 22 q[0]=1;point[1]=0; 23 while(t<w) 24 { 25 now=q[t++]; 26 for(int i=1;i<=26;i++) 27 { 28 if(!a[now][i])continue; 29 int k=point[now]; 30 while(!a[k][i])k=point[k]; 31 point[a[now][i]]=a[k][i]; 32 q[w++]=a[now][i]; 33 } 34 } 35 } 36 void solve() 37 { 38 int k=1,l=strlen(m); 39 for(int i=0;i<l;i++) 40 { 41 mark[k]=1; 42 int t=m[i]-'a'+1; 43 while(!a[k][t])k=point[k]; 44 k=a[k][t]; 45 if(!mark[k]) 46 for(int j=k;j;j=point[j]) 47 { 48 ans+=danger[j]; 49 danger[j]=0; 50 } 51 } 52 printf("%d\n",ans); 53 } 54 int main() 55 { 56 scanf("%d",&T); 57 while(T--) 58 { 59 sz=1;ans=0; 60 scanf("%d",&n); 61 for(int i=1;i<=26;i++)a[0][i]=1; 62 while(n--) 63 { 64 scanf("%s",s); 65 ins(); 66 } 67 acmach(); 68 scanf("%s",m); 69 solve(); 70 for(int i=1;i<=sz;i++) 71 { 72 point[i]=danger[i]=mark[i]=0; 73 for(int j=1;j<=26;j++) 74 a[i][j]=0; 75 } 76 } 77 return 0; 78 }