Keywords Search(AC自动机模板)
Keywords Search
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 68211 Accepted Submission(s): 23017
Problem Description
In the modern time, Search engine came into the life of everybody like Google, Baidu, etc.
Wiskey also wants to bring this feature to his image retrieval system.
Every image have a long description, when users type some keywords to find the image, the system will match the keywords with description of image and show the image which the most keywords be matched.
To simplify the problem, giving you a description of image, and some keywords, you should tell me how many keywords will be match.
Input
First line will contain one integer means how many cases will follow by.
Each case will contain two integers N means the number of keywords and N keywords follow. (N <= 10000)
Each keyword will only contains characters 'a'-'z', and the length will be not longer than 50.
The last line is the description, and the length will be not longer than 1000000.
Output
Print how many keywords are contained in the description.
Sample Input
Sample Output
3
//题意:多个(<=10000)模式串(len<=50),一个匹配串(len<10^6),求匹配数
//AC自动机模板题
指针
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define MX 1000005 4 5 struct Node{ 6 Node * nex[26]; 7 Node * fail; 8 int sum; 9 Node(){ 10 for (int i=0;i<26;i++) nex[i]=NULL; 11 fail=NULL; sum=0; 12 } 13 }*root; 14 15 int n, cnt; 16 char str[MX]; 17 18 void Init(){ 19 root=new(Node); 20 } 21 22 void Insert(char *s) 23 { 24 int len = strlen(s); 25 Node * p=root; 26 for (int i=0;i<len;i++) 27 { 28 int x = s[i]-'a'; 29 if (p->nex[x]==NULL) p->nex[x]=new(Node); 30 p=p->nex[x]; 31 } 32 p->sum++; 33 } 34 35 void Build_fail() 36 { 37 queue<Node *> Q; 38 Q.push(root); 39 while (!Q.empty()) 40 { 41 Node *p = Q.front(); Q.pop(); 42 for (int i=0;i<26;i++) 43 { 44 if (p->nex[i]) 45 { 46 if (p==root) 47 p->nex[i]->fail=root; 48 else 49 { 50 Node * tmp = p->fail; 51 while (tmp) 52 { 53 if (tmp->nex[i]) 54 { 55 p->nex[i]->fail=tmp->nex[i]; 56 break; 57 } 58 tmp = tmp->fail; 59 } 60 if (tmp==NULL) p->nex[i]->fail=root; // 61 } 62 Q.push(p->nex[i]); 63 } 64 } 65 } 66 } 67 68 void AC_auto(char *s) 69 { 70 int len = strlen(s); 71 Node *p=root, *tmp; 72 for (int i=0;i<len;i++) 73 { 74 int x = s[i]-'a'; 75 while (p->nex[x]==NULL && p!=root) p=p->fail; 76 p=p->nex[x]; 77 if (!p) p=root; 78 tmp = p; 79 while (tmp) 80 { 81 if (tmp->sum>=0) 82 { 83 cnt+=tmp->sum; 84 tmp->sum=-1; 85 } else break; 86 tmp=tmp->fail; 87 } 88 } 89 } 90 91 void _delete(Node *p) 92 { 93 for (int i=0;i<26;i++) 94 { 95 if (p->nex[i]) 96 _delete(p->nex[i]); 97 } 98 delete(p); 99 } 100 101 int main() 102 { 103 int T; 104 scanf("%d",&T); 105 while (T--) 106 { 107 scanf("%d",&n); 108 Init(); 109 for (int i=1;i<=n;i++) 110 { 111 scanf("%s",str); 112 Insert(str); 113 } 114 scanf("%s",str); 115 cnt = 0; 116 Build_fail(); 117 AC_auto(str); 118 printf("%d\n",cnt); 119 _delete(root); 120 } 121 return 0; 122 }