HDU2896 病毒侵袭 AC自动机模板
各种MLE,这模板感觉有问题,next数组开128也会MLE,实际上可见字符为编号32~126,只用开100就行。
1 #include <iostream> 2 #include <cstdio> 3 #include <string.h> 4 #include <algorithm> 5 #include <queue> 6 #pragma warning ( disable : 4996 ) 7 using namespace std; 8 9 inline int Max(int a,int b) { return a>b?a:b; } 10 inline int Min(int a,int b) { return a>b?b:a; } 11 const int inf = 0x3f3f3f3f; 12 const int maxn = 1e6+5; 13 const int maxk = 100; 14 15 int N, M, tot; 16 int ans[5]; 17 char str[205], test[10005]; 18 19 struct node { 20 node* next[maxk]; 21 node* fail; 22 int code; 23 bool end; 24 node() { 25 memset( next, NULL, sizeof(next) ); 26 fail = NULL; 27 code = 0; end = false; 28 } 29 }; 30 31 void insert( node* root, int x ) 32 { 33 node* p = root; 34 int len = strlen(str); 35 int tmp; 36 37 for ( int i = 0; i < len; i++ ) 38 { 39 tmp = str[i]-32; 40 if ( p->next[tmp] == NULL ) 41 p->next[tmp] = new node(); 42 p = p->next[tmp]; 43 p->code = x; 44 } 45 p->end = true; 46 } 47 48 void getnotfail( node* root ) 49 { 50 queue<node*> q; 51 root->fail = NULL; 52 q.push(root); 53 while (!q.empty()) 54 { 55 node *run= q.front(); q.pop(); 56 node *tmp = NULL; 57 for ( int i = 0; i < maxk; i++ ) 58 { 59 if ( run->next[i] ) 60 { //如果节点是初始节点,则它的子节点的失败指针全部指向root 61 if(run==root) run->next[i]->fail = root; 62 else 63 { 64 tmp = run->fail; //tmp为它的父节点的上层节点 65 while (tmp) 66 { 67 if(tmp->next[i]) //寻找tmp的第i个子节点,如果存在,则run的fail指针指向它 68 { run->next[i]->fail = tmp->next[i]; break; } 69 tmp = tmp->fail; 70 } 71 if(tmp==NULL) 72 run->next[i]->fail = root; 73 } 74 q.push(run->next[i]); 75 } 76 } 77 } 78 } 79 80 int query( node* r ) 81 { 82 int cnt = 0; 83 int len = strlen(test); 84 node* p = r; 85 for ( int i = 0; i < len; i++ ) 86 { 87 int x = test[i]-32; 88 while (!p->next[x]&&p!=r) p = p->fail; 89 90 p = p->next[x]; 91 if (!p) p = r; 92 node *tmp = p; 93 94 while (tmp!=r&&tmp->end) 95 { 96 ans[cnt++] = tmp->code; 97 tmp = tmp->fail; 98 } 99 } 100 return cnt; 101 } 102 103 int main() 104 { 105 106 while ( ~scanf("%d", &N )) 107 { 108 node* r = new node; 109 110 for ( int i = 1; i <= N; i++ ) 111 { scanf("%s", str); insert(r, i); } 112 getnotfail(r); 113 cin >> M; 114 115 116 for ( int i = 1; i <= M; i++ ) 117 { 118 scanf( "%s", test ); 119 int num = query(r); 120 if (num) 121 { 122 sort(ans, ans + num); 123 printf( "web %d:", i ); 124 for ( int j = 0; j < num; j++ ) 125 printf(" %d", ans[j]); 126 cout << endl; 127 tot++; 128 memset( ans, 0, sizeof(ans) ); 129 } 130 } 131 printf("total: %d\n", tot); 132 } 133 return 0; 134 }
什么时候能够不再这么懒惰