Virus attacks
Problem's link: http://acm.hdu.edu.cn/showproblem.php? PID = 1, 2896
Mean:
Chinese question, not explained.
Analyze:
The Application of AC automatic machine, multi-mode string matching. There are several details to be aware of. These details have been stuck for a long time.
1) the output website number is different from the final number of virus websites;
2) set the next pointer to 128, otherwise the stack will pop up;
3) Similarly, when char is converted to int, the base must be set to 31;
Time Complexity: O (n) + O (ML)
Source code:
// Memory time // 1347 K 0 Ms //: snarl_jsb // 2014-09-30-11.01 # include <algorithm> # include <cstdio> # include <cstring> # include <cstdlib> # include <iostream> # include <vector> # include <queue> # include <stack> # include <map> # include <string> # include <climits> # include <cmath> # define ll long longusing namespace STD; const int n = 10010; char STR [N]; struct node {node * Next [128]; // each node corresponds to the pointer node * fail with 128 letters; // mismatched pointer int Count; // int num; node () // constructor initialization {for (INT I = 0; I <128; I ++) next [I] = NULL; count = 0; fail = NULL; num = 0 ;}} * Q [50 * n]; node * root; int head, tail; void insert (char * STR, int num) // insert a word. it is equivalent to constructing a trie tree {node * P = root; int I = 0, index; while (STR [I]) {Index = STR [I]-31; // convert it to a relative number to save if (p-> next [Index] = NULL) // The letter has not been inserted with p-> next [Index] = new node (); // apply for a node P = p-> next [Index] for the letter; // move it to the next node I ++;} p-> count ++; // records the total number of times that words at the node are inserted. P-> num = num;} void build_ac_automation (node * root) // BFS establishes the Fail pointer {root-> fail = NULL; Q [tail ++] = root; while (Head <tail) {node * temp = Q [head ++]; node * P = NULL; For (INT I = 0; I <128; I ++) {If (temp-> next [I]! = NULL) {If (temp = root) temp-> next [I]-> fail = root; else {P = temp-> fail; while (P! = NULL) {If (p-> next [I]! = NULL) {temp-> next [I]-> fail = p-> next [I]; break;} p = p-> fail ;} if (P = NULL) temp-> next [I]-> fail = root;} Q [tail ++] = temp-> next [I] ;}} int Total = 0; int query (node * root, int num) // matching + statistics {int I = 0, CNT = 0, index; node * P = root; int idx = 0; int ans [100]; while (STR [I]) {Index = STR [I]-31; while (p-> next [Index] = NULL & P! = Root) // The prefix is the same, so no matter which pointer goes to the node where count is not 0, then the words represented by this node match successfully. P = p-> fail; // if the word is not matched, the p Pointer Points to P-> fail. (equivalent to the next array of KMP) P = p-> next [Index]; // because the current location is the parent node, so you need to move down a position if (P = NULL) P = root; // If the match fails, move to root and start matching node * temp = P again; // while (temp! = Root & temp-> count! =-1) // statistics -- if the match is successful, count> 1 indicates the number of words that the node represents; otherwise, the node does not have the word {If (temp-> count> 0) {CNT ++; // count the number of times this word appears ans [++ idx] = temp-> num;} // temp-> COUNT =-1; // mark it as-1, indicates that the word has been added to CNT. You do not need to repeat the statistics temp = temp-> fail next time. // you can determine the matching condition of the entire chain.} I ++ ;} if (idx = 0) return 0; printf ("Web % d:", num); sort (ANS + 1, ANS + 1 + idx); Total ++; for (INT I = 1; I <idx; ++ I) {printf ("% d", ANS [I]);} printf ("% d \ n ", ans [idx]); Return CNT;} int main () {int N; CIN> N; head = tail = 0; root = new node (); for (INT I = 1; I <= N; ++ I) {scanf ("% s", STR); insert (STR, I) ;}build_ac_automation (Root ); // build int m; CIN> m; Total = 0; For (INT I = 1; I <= m; ++ I) {scanf ("% s ", str); query (root, I);} printf ("Total: % d \ n", total); Return 0 ;}
AC automatic mechanism-application of multi-mode string matching --- HDU 2896