Virus attack continues
Problem's link: http://acm.hdu.edu.cn/showproblem.php? PID = 1, 3065
Mean:
Chinese question, not explained.
Analyze:
Application of AC automatic machines. This topic needs to store all the mode strings, and the value of base must be clarified. Because the mode strings are uppercase letters, we can use pruning to accelerate the process.
Time Complexity:O (n) + O (ML)
Source code:
// Memory time // 1347 K 0 Ms //: snarl_jsb // 2014-09-30-21.00 # 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; char backup [1002] [53]; int res [1002]; const int n = 1010; char STR [2000010]; struct node {node * Next [26]; // Each node corresponds to the 26-letter pointer node * fail; // mismatch pointer int count; // int num; node () // constructor initialization {for (INT I = 0; I <26; I ++) next [I] = NULL; Count = 0; num = 0; fail = NULL ;}} * 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]-'A '; // 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]; // move it to the next I ++;} p-> count ++; // record the total number of times the words at the node are inserted p-> num = num;} void build_ac_automation (node * root) // BFS creates a fail pointer {root-> fail = NULL; Q [tail ++] = root; while (Head <tail) {node * temp = Q [head ++]; node * P = NULL; For (INT I = 0; I <26; 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 query (node * root) // match + statistics {int I = 0, CNT = 0, index; node * P = root; while (STR [I]) {Index = STR [I]-'A'; If (index <0 | index> 25) // note that the virus contains only uppercase letters, therefore, pruning is required here. If pruning is not performed, you can add {P = root; I ++; continue;} in other places ;} 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> 0) // 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 {// CNT + = temp-> count; // count the number of times this word appears res [temp-> num] ++; // 1 // temp-> COUNT =-1 will be added for each backtracking ;//!!!!!!!!!!!!!!!!! (If you want to repeat statistics, please remove this sentence )!!!!!!!! Marked as-1, indicating that the word has been added to CNT temp = temp-> fail; // you can determine the matching condition of the entire chain} I ++;} return CNT ;} int main () {int n, m; while (CIN> N) {head = tail = 0; // reset root = new node (); // apply for a new root node memset (backup, 0, sizeof (Backup); memset (Res, 0, sizeof (RES); For (INT I = 1; I <= N; ++ I) {scanf ("% s", STR); strcpy (Backup [I], STR); insert (STR, I );} build_ac_automation (Root); scanf ("% s", STR); query (Root); For (INT I = 1; I <= N; ++ I) {If (RES [I]) {printf ("% s: % d \ n", backup [I], Res [I]) ;}} return 0 ;}
AC --AC -application of multi-mode string matching --- HDU 3065