题目链接:Keywords Search
题意:给你n个字符串不长度超过50,然后在给一个串ss问有多少个串在这个ss串里面出现过,
题解:ac自动机的入门模板题,学习资料,要求先会kmp,和字典树。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e4*50+100; 4 const int N=1e4*50+100; 5 char op[55],ss[(int)1e6+10]; 6 struct ac_auto 7 { 8 int nxt[N][26],ed[N],fail[N],cn,rt; 9 ac_auto(){} 10 void init(){ 11 memset(nxt,-1,sizeof(nxt)); 12 memset(ed,0,sizeof(ed)); 13 memset(fail,-1,sizeof(fail)); 14 cn=0; 15 rt=new_node(); 16 } 17 int new_node() 18 { 19 return cn++; 20 } 21 void insert(char *s) 22 { 23 int len=strlen(s); 24 int p=rt; 25 for(int i=0;i<len;i++) 26 { 27 int x=s[i]-'a'; 28 if(nxt[p][x]==-1)nxt[p][x]=new_node(); 29 p=nxt[p][x]; 30 } 31 ed[p]++; 32 } 33 void get_fail() 34 { 35 queue<int>que; 36 que.push(rt); 37 while(!que.empty()) 38 { 39 int s=que.front();que.pop(); 40 for(int i=0;i<26;i++) 41 { 42 if(nxt[s][i]!=-1) 43 { 44 if(s==rt) 45 { 46 fail[nxt[s][i]]=rt; 47 } 48 else 49 { 50 int p=fail[s]; 51 while(p!=-1) 52 { 53 if(nxt[p][i]!=-1) 54 { 55 fail[nxt[s][i]]=nxt[p][i];break; 56 } 57 p=fail[p]; 58 } 59 if(p==-1)fail[nxt[s][i]]=rt; 60 } 61 que.push(nxt[s][i]); 62 } 63 64 } 65 } 66 } 67 int ac_automation(char *s) 68 { 69 int p=rt;int ans=0; 70 int len=strlen(s); 71 for(int i=0;i<len;i++) 72 { 73 int x=s[i]-'a'; 74 while(p!=-1&&nxt[p][x]==-1)p=fail[p]; 75 if(p==-1)p=rt; 76 else p=nxt[p][x]; 77 int tmp=p; 78 while(tmp!=rt) 79 { 80 if(ed[tmp]>0)ans+=ed[tmp],ed[tmp]=0; 81 else break; 82 tmp=fail[tmp]; 83 } 84 } 85 return ans; 86 } 87 }ac; 88 int main() 89 { 90 int T; 91 scanf("%d",&T); 92 while(T--) 93 { 94 ac.init(); 95 int n; 96 scanf("%d",&n); 97 for(int i=0;i<n;i++)scanf("%s",op),ac.insert(op); 98 ac.get_fail(); 99 scanf("%s",ss); 100 printf("%d ",ac.ac_automation(ss)); 101 } 102 }