hdu 3065 病毒侵袭持续中
http://acm.hdu.edu.cn/showproblem.php?pid=3065
继续简单AC自动机,1y~
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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