hdu 3065 病毒侵袭持续中

http://acm.hdu.edu.cn/showproblem.php?pid=3065

  继续简单AC自动机,1y~

View Code
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <set>
  5 #include <cstdlib>
  6 
  7 using namespace std;
  8 
  9 const int kind = 256;
 10 const int maxn = 51 * 1001;
 11 
 12 struct Node{
 13     int fail;
 14     int next[kind];
 15     int count;
 16     void init(){
 17         fail = -1;
 18         count = 0;
 19         memset(next, -1, sizeof(next));
 20     }
 21 }node[maxn];
 22 
 23 char keyword[51];
 24 char str[2000005];
 25 int head, tail, nodeUsed;
 26 int q[maxn];
 27 
 28 void insert(char *s, int root, int num){
 29     int p = root;
 30     int i = 0, index;
 31 
 32     while (s[i]){
 33         index = s[i];
 34         if (node[p].next[index] == -1){
 35             node[p].next[index] = nodeUsed;
 36             node[nodeUsed].init();
 37             nodeUsed++;
 38         }
 39         p = node[p].next[index];
 40         i++;
 41     }
 42     node[p].count = num;
 43 }
 44 
 45 void build(int root){
 46     int i;
 47 
 48     node[root].fail = -1;
 49     head = tail = 0;
 50     q[head++] = root;
 51     while (head != tail){
 52         int temp = q[tail++];
 53         int p = -1;
 54 
 55         for (i = 0; i < kind; i++){
 56             if (node[temp].next[i] != -1){
 57                 if (temp == root) node[node[temp].next[i]].fail = root;
 58                 else{
 59                     p = node[temp].fail;
 60                     while (p != -1){
 61                         if (node[p].next[i] != -1){
 62                             node[node[temp].next[i]].fail = node[p].next[i];
 63                             break;
 64                         }
 65                         p = node[p].fail;
 66                     }
 67                     if (p == -1) node[node[temp].next[i]].fail = root;
 68                 }
 69                 q[head++] = node[temp].next[i];
 70             }
 71         }
 72     }
 73 }
 74 
 75 char buf[1001][51];
 76 int cnt[1001];
 77 
 78 void query(int root){
 79     int i = 0, index;
 80     int p = root;
 81 
 82     memset(cnt, 0, sizeof(cnt));
 83     while (str[i]){
 84         index = str[i];
 85         while (node[p].next[index] == -1 && p != root) p = node[p].fail;
 86         p = node[p].next[index];
 87         p = (p == -1) ? root : p;
 88 
 89         if (node[p].count) cnt[node[p].count]++;
 90         i++;
 91     }
 92 }
 93 
 94 void traverse(int root){
 95     if (root == -1) return ;
 96     printf("root %d\n", root);
 97     printf("fail %d\n", node[root].fail);
 98     printf("count %d\n", node[root].count);
 99     for (int i = 0; i < kind; i++){
100         if (node[root].next[i] == -1) continue;
101         printf("%c %d\n", i + 'a', node[root].next[i]);
102     }
103     puts("");
104     for (int i = 0; i < kind; i++){
105         traverse(node[root].next[i]);
106     }
107 }
108 
109 int main(){
110     int n;
111 
112 //freopen("in", "r", stdin);
113     while (~scanf("%d", &n)){
114         int root = 0;
115 
116         node[0].init();
117         nodeUsed = 1;
118 
119         for(int i = 1; i <= n; i++){
120             scanf("%s", keyword);
121             strcpy(buf[i], keyword);
122             insert(keyword, root, i);
123         }
124         build(root);
125 //traverse(root);
126 //puts("Built!");
127 
128         scanf("%s", str);
129         query(root);
130         for (int i = 1; i <= n; i++){
131             if (cnt[i]) printf("%s: %d\n", buf[i], cnt[i]);
132         }
133     }
134 
135     return 0;
136 }

——written by Lyon

原文地址:https://www.cnblogs.com/LyonLys/p/hdu_3065_Lyon.html