AC自动机裸题,建议刚开始学习的同学看一下这篇博客,讲的很详细 https://blog.csdn.net/u013371163/article/details/60469534
这个是向kuangbin大佬学的写法,感觉很棒啊!
1 #include <iostream> 2 #include <stdio.h> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 const int MAXN=6e5; 7 struct Tire 8 { 9 int next[MAXN][26],fail[MAXN],last[MAXN]; 10 int L; 11 int root; 12 int newnode() 13 { 14 for(int i=0;i<26;i++) 15 next[L][i]=-1; 16 last[L++]=0; 17 return L-1; 18 } 19 void init() 20 { 21 L=0; 22 root=newnode(); 23 } 24 void Insert(char *str) //将模式串插入字典树 25 { 26 int len=strlen(str); 27 int now=root; 28 for(int i=0;i<len;i++) 29 { 30 int x=str[i]-'a'; 31 if(next[now][x]==-1) 32 { 33 next[now][x]=newnode(); 34 } 35 now=next[now][x]; 36 } 37 last[now]++; 38 } 39 void build() //在字典树上建立fail指针 40 { 41 int now=root; 42 int temp; 43 fail[root]=root; //root的fail指针指向root 44 queue<int> Q; 45 for(int i=0;i<26;i++) 46 { 47 if(next[root][i]==-1) 48 next[root][i]=root; 49 else 50 { 51 fail[next[root][i]]=root; 52 Q.push(next[root][i]); 53 } 54 55 } 56 while(!Q.empty()) 57 { 58 now=Q.front(); 59 Q.pop(); 60 for(int i=0;i<26;i++) 61 { 62 if(next[now][i]==-1) 63 next[now][i]=next[fail[now]][i]; 64 else 65 { 66 fail[next[now][i]]=next[fail[now]][i]; 67 Q.push(next[now][i]); 68 } 69 } 70 } 71 } 72 int query(char *str) 73 { 74 int len=strlen(str); 75 int now=root; 76 int ans=0; 77 for(int i=0;i<len;i++) 78 { 79 int x=str[i]-'a'; 80 now=next[now][x]; 81 int temp=now; 82 while(temp!=root) 83 { 84 ans+=last[temp]; 85 last[temp]=0; 86 temp=fail[temp]; 87 } 88 } 89 return ans; 90 } 91 }; 92 char pattern[MAXN<<2]; 93 Tire ac; 94 int main() 95 { 96 int t,n; 97 scanf("%d",&t); 98 while(t--) 99 { 100 ac.init(); 101 scanf("%d",&n); 102 for(int i=0;i<n;i++) 103 { 104 scanf("%s",pattern); 105 ac.Insert(pattern); 106 } 107 ac.build(); 108 scanf("%s",pattern); 109 int ans=ac.query(pattern); 110 printf("%d\n",ans); 111 } 112 return 0; 113 }