标签:
题意:就是求目标串中出现了几个模式串。
思路:用int型的end数组记录出现,AC自动机即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<string> 6 #include<algorithm> 7 #include<queue> 8 #define maxn 500005 9 int T,n; 10 char s[2000005]; 11 struct Trie{ 12 int root,L; 13 int next[maxn][27],fail[maxn],end[maxn]; 14 int newnode(){ 15 for (int i=0;i<26;i++) 16 next[L][i]=-1; 17 end[L++]=0; 18 return L-1; 19 } 20 void clear(){ 21 L=0;root=newnode(); 22 } 23 void insert(char s[]){ 24 int now=root,len=strlen(s); 25 for (int i=0;i<len;i++){ 26 if (next[now][s[i]-‘a‘]==-1) next[now][s[i]-‘a‘]=newnode(); 27 now=next[now][s[i]-‘a‘]; 28 } 29 end[now]++; 30 } 31 void build(){ 32 std::queue<int>Q; 33 int now=root; 34 for (int i=0;i<26;i++) 35 if (next[now][i]==-1) next[now][i]=root; 36 else 37 fail[next[now][i]]=root,Q.push(next[now][i]); 38 while (!Q.empty()){ 39 int now=Q.front(); 40 Q.pop(); 41 for (int i=0;i<26;i++){ 42 if (next[now][i]==-1) 43 next[now][i]=next[fail[now]][i]; 44 else{ 45 fail[next[now][i]]=next[fail[now]][i]; 46 Q.push(next[now][i]); 47 } 48 } 49 } 50 } 51 int query(char s[]){ 52 int now=root,len=strlen(s),res=0; 53 for (int i=0;i<len;i++){ 54 now=next[now][s[i]-‘a‘]; 55 int tmp=now; 56 while (tmp!=root){ 57 res+=end[tmp]; 58 end[tmp]=0; 59 tmp=fail[tmp]; 60 } 61 } 62 return res; 63 } 64 }ac; 65 int main(){ 66 scanf("%d",&T); 67 while (T--){ 68 scanf("%d",&n); 69 ac.clear(); 70 for (int i=0;i<n;i++){ 71 scanf("%s",s); 72 ac.insert(s); 73 } 74 ac.build(); 75 scanf("%s",s); 76 printf("%d\n",ac.query(s)); 77 } 78 }
HDU 2222 Keywords Search (AC自动机)
标签:
原文地址:http://www.cnblogs.com/qzqzgfy/p/5551734.html