Virus attack continues
Time Limit: 2000/1000 MS (Java/others) memory limit: 32768/32768 K (Java/Others)
Total submission (s): 6721 accepted submission (s): 2372
Problem description small t thank you very much for helping solve his previous problem. However, virus attacks continue. With the unremitting efforts of Mr. T, he discovered the "source of evil" in the Internet ". This is a huge virus website. It has many viruses, but the website contains very strange viruses. These viruses have very short signatures and only contain "uppercase letters ". Of course, little t really wants to harm the people, but little t never fights an unprepared war. Know yourself and know what you are doing. The first thing small T wants to do is to know the characteristics of this virus Website: How many different viruses are contained, and how many times each virus appears. Can you help him?
The first line of input, an integer N (1 <= n <= 1000), indicates the number of virus signatures.
In the next n rows, each line represents a virus pattern. The character string must be 1-50 characters long and only contain "uppercase letters ". No two virus signatures are identical.
In the next line, it indicates the source code of the website "the source code of all evil". The source code string length is within 2000000. The characters in the string are both visible ASCII characters (excluding carriage return ).
Output is one per line in the following format, and the number of times each virus appears. No output is required for a virus that does not appear.
Virus pattern: number of occurrences
There is a space after the colon, Which is output in the input order of the virus signature.
Sample input3aabbccooxxcc % daaaoen... end
Sample outputaa: 2cc: 1
Hint Hit: all situations not mentioned in the title description should be considered. For example, two virus signatures may contain one another or overlap one another. The counting policy can also be inferred to some extent from the sample.
Source 2009 multi-university training contest 16-host by NIT is taken from the http://www.cppblog.com/mythit/archive/2009/04/21/80633.html build failure pointer section: after constructing the tire, the next job is to construct the failure pointer. The process of constructing the failure pointer is summarized as one sentence: Set the letter on this node to C and follow his father's failure pointer until he reaches a node, his son also has a node with the letter C. Then point the failure pointer of the current node to the son of C. If the root fails to be found, point the failure pointer to the root. For specific operations, you only need to: First add the root to the queue (the root failure Pointer Points to itself or null). Then, every time we process a vertex, we add all its sons to the queue, the queue is empty. Query: the matching process is divided into two situations: (1) the current character matches, indicating that a path along the tree edge from the current node can reach the target character, in this case, you only need to move the path to the next node to continue matching, and the target string pointer moves to the next character to continue matching; (2) the current character does not match, the character pointing to the failed pointer of the current node is matched, and the matching process ends with the pointer pointing to the root. Repeat any of the two processes until the pattern string ends. Code:
1 /*hdu 3065 Ac-自动机*/ 2 //#define LOCAL 3 #include<queue> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<iostream> 8 #include<algorithm> 9 using namespace std; 10 int res; 11 struct Trie 12 { 13 struct Trie *fail; 14 struct Trie *child[127]; 15 int id; 16 }; 17 char s1[1001][55]; 18 char t1[2000005]; 19 int ans[1002]; 20 void _insert(char *s,Trie *root,int id) //构造一下rie树 21 { 22 Trie *cur=root,*newcur; 23 for(int i=0;s[i];i++) 24 { 25 int idx=s[i]-32; 26 if(cur->child[idx]==NULL) 27 { 28 newcur=new Trie; 29 for(int j=0;j<127;j++) 30 newcur->child[j]=NULL; 31 newcur->fail=NULL; 32 newcur->id=0; 33 cur->child[idx]=newcur; 34 } 35 cur=cur->child[idx]; 36 } 37 cur->id=id; 38 } 39 //构造失败指针 40 void ac_fail(Trie *root) 41 { 42 Trie *cur,*q ; 43 queue<Trie*>tre; 44 tre.push(root); 45 while(!tre.empty()) 46 { 47 cur=tre.front(); 48 tre.pop(); 49 for(int i=0;i<127;i++) 50 { 51 if(cur->child[i]) 52 { 53 if(cur==root) 54 cur->child[i]->fail=root; 55 else 56 { 57 q=cur; 58 while(q->fail){ 59 if(q->fail->child[i]) 60 { 61 cur->child[i]->fail=q->fail->child[i]; 62 break; 63 } 64 q=q->fail; 65 } 66 if(!q->fail) 67 cur->child[i]->fail=root; 68 } 69 tre.push(cur->child[i]); 70 } 71 } 72 } 73 } 74 //查询 75 void solve(char *s,Trie *root) 76 { 77 Trie *cur=root,*newcur; 78 for(int i=0 ; s[i] ;i++ ) 79 { 80 while(cur->child[s[i]-32]==NULL&&cur!=root) 81 cur=cur->fail; 82 cur=cur->child[s[i]-32]; 83 if(cur==NULL) cur=root; 84 newcur=cur; 85 while(newcur!=root&&newcur->id>0) 86 { 87 ans[newcur->id]++; 88 newcur=newcur->fail; 89 } 90 } 91 } 92 void del(Trie *root) 93 { 94 if(!root) return ; 95 for(int i=0;i<127;i++) 96 if(root->child[i]) 97 del(root->child[i]); 98 delete root; 99 }100 void work(int n)101 {102 for(int i=1;i<=n;i++)103 if(ans[i]>0)104 {105 printf("%s: %d\n",s1[i],ans[i]);106 }107 }108 int main()109 {110 #ifdef LOCAL111 freopen("test.in","r",stdin);112 #endif113 int n,i;114 while(scanf("%d",&n)!=EOF)115 {116 Trie *root=new Trie;117 for(i=0;i<127;i++)118 root->child[i]=NULL;119 root->fail=NULL;120 root->id=0;121 memset(ans,0,sizeof(ans));122 for(i=1;i<=n;i++)123 {124 scanf("%s",s1[i]);125 _insert(s1[i],root,i);126 }127 ac_fail(root);128 scanf("%s",t1);129 solve(t1,root);130 work(n);131 del(root);132 }133 return 0;134 }
View code
HDU ---- (3065) Sustained virus (AC automated machine)