HDU 2222 Keywords Search(AC自动机模版)
比着模版改的。改成静态的,一直在RE与超内存之间徘徊,最后出现了WA,忘记了一个初始化。。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 using namespace std; 6 char str[1000001]; 7 int t; 8 int tire[252222][26]; 9 int que[352222]; 10 int o[252222]; 11 int fail[252222]; 12 void CL() 13 { 14 memset(tire,-1,sizeof(tire)); 15 memset(fail,-1,sizeof(fail)); 16 memset(o,0,sizeof(o)); 17 t = 1; 18 } 19 void insert(char *s) 20 { 21 int i,root,len; 22 len = strlen(s); 23 root = 0; 24 for(i = 0;i < len;i ++) 25 { 26 if(tire[root][s[i]-'a'] == -1) 27 tire[root][s[i]-'a'] = t ++; 28 root = tire[root][s[i]-'a']; 29 } 30 o[root] ++; 31 } 32 void build_ac() 33 { 34 int head,tail,front,temp,i; 35 head = tail = 0; 36 que[tail++] = 0; 37 while(head != tail) 38 { 39 front = que[head++]; 40 for(i = 0;i < 26;i ++) 41 { 42 if(tire[front][i] != -1) 43 { 44 if(front == 0) 45 fail[tire[front][i]] = 0; 46 else 47 { 48 temp = fail[front]; 49 while(temp != -1) 50 { 51 if(tire[temp][i] != -1) 52 { 53 fail[tire[front][i]] = tire[temp][i]; 54 break; 55 } 56 temp = fail[temp]; 57 } 58 if(temp == -1) fail[tire[front][i]] = 0; 59 } 60 que[tail++] = tire[front][i]; 61 } 62 } 63 } 64 } 65 int query(char *s) 66 { 67 int i,len,root,temp,ans,key; 68 ans = 0; 69 root = 0; 70 len = strlen(s); 71 for(i = 0;i < len;i ++) 72 { 73 temp = s[i] - 'a'; 74 while(tire[root][temp] == -1&&root != 0) 75 root = fail[root]; 76 root = tire[root][temp]; 77 if(root == -1) root = 0; 78 key = root; 79 while(key != 0&&o[key] != -1) 80 { 81 ans += o[key]; 82 o[key] = -1; 83 key = fail[key]; 84 } 85 86 } 87 return ans; 88 } 89 int main() 90 { 91 int cas,i,n; 92 scanf("%d",&cas); 93 while(cas--) 94 { 95 scanf("%d",&n); 96 CL(); 97 for(i = 0;i < n;i ++) 98 { 99 scanf("%s",str); 100 insert(str); 101 } 102 build_ac(); 103 scanf("%s",str); 104 printf("%d\n",query(str)); 105 } 106 return 0; 107 }
新的模版,写起来更短一点。。还要理解一下。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 using namespace std; 6 char str[1000001]; 7 int t; 8 int tire[252222][26]; 9 int que[352222]; 10 int o[252222]; 11 int fail[252222]; 12 void CL() 13 { 14 memset(tire,-1,sizeof(tire)); 15 memset(o,0,sizeof(o)); 16 t = 1; 17 } 18 void insert(char *s) 19 { 20 int i,root,len; 21 len = strlen(s); 22 root = 0; 23 for(i = 0;i < len;i ++) 24 { 25 if(tire[root][s[i]-'a'] == -1) 26 tire[root][s[i]-'a'] = t ++; 27 root = tire[root][s[i]-'a']; 28 } 29 o[root] ++; 30 } 31 void build_ac() 32 { 33 int head,tail,front,i; 34 head = tail = 0; 35 for (i = 0; i < 26; i++) 36 { 37 if (tire[0][i] != -1) 38 { 39 fail[tire[0][i]] = 0; 40 que[tail++] = tire[0][i]; 41 } 42 else 43 { 44 tire[0][i] = 0; 45 } 46 } 47 while(head != tail) 48 { 49 front = que[head++]; 50 for(i = 0; i < 26; i ++) 51 { 52 if(tire[front][i] != -1) 53 { 54 que[tail++] = tire[front][i]; 55 fail[tire[front][i]] = tire[fail[front]][i]; 56 } 57 else 58 { 59 tire[front][i] = tire[fail[front]][i]; 60 } 61 } 62 } 63 } 64 int query(char *s) 65 { 66 int i,len,root,temp,ans,key; 67 ans = 0; 68 root = 0; 69 len = strlen(s); 70 for(i = 0;i < len;i ++) 71 { 72 temp = s[i] - 'a'; 73 root = tire[root][temp]; 74 key = root; 75 while(key != 0&&o[key] != -1) 76 { 77 ans += o[key]; 78 o[key] = -1; 79 key = fail[key]; 80 } 81 } 82 return ans; 83 } 84 int main() 85 { 86 int cas,i,n; 87 scanf("%d",&cas); 88 while(cas--) 89 { 90 scanf("%d",&n); 91 CL(); 92 for(i = 0;i < n;i ++) 93 { 94 scanf("%s",str); 95 insert(str); 96 } 97 build_ac(); 98 scanf("%s",str); 99 printf("%d\n",query(str)); 100 } 101 return 0; 102 }