ac自动机的模板题
说2个注意的地方 一是题目说明包含所有ASCII字符,可以开到0-127 包含空格
题目会输入多个源串,在加完当前的val值时,不应清0,可以开个标记数组。
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 using namespace std; 11 #define N 100010 12 #define M 510 13 #define LL long long 14 #define INF 0xfffffff 15 const double eps = 1e-8; 16 const double pi = acos(-1.0); 17 const double inf = ~0u>>2; 18 const int child_num = 128; 19 int g; 20 int o[M]; 21 char s[N]; 22 bool f[M]; 23 class ACAutomo 24 { 25 private: 26 int ch[N][child_num]; 27 int val[N]; 28 int fail[N]; 29 int Q[N]; 30 int id[128]; 31 int sz; 32 public: 33 void init() 34 { 35 fail[0] = 0; 36 for(int i = 0; i < child_num ; i++) 37 id[i] = i; 38 } 39 void reset() 40 { 41 memset(ch[0],0,sizeof(ch[0])); 42 sz = 1; 43 } 44 void insert(char *a,int key) 45 { 46 int p = 0 ; 47 for( ; *a ; a++) 48 { 49 int d = id[*a]; 50 if(ch[p][d]==0) 51 { 52 memset(ch[sz],0,sizeof(ch[sz])); 53 val[p] = 0; 54 ch[p][d] = sz++; 55 } 56 p = ch[p][d]; 57 } 58 val[p]=key; 59 } 60 void construct() 61 { 62 int i,head=0,tail = 0; 63 for(i = 0 ;i < child_num ; i++) 64 { 65 if(ch[0][i]) 66 { 67 Q[tail++] = ch[0][i]; 68 fail[ch[0][i]] = 0; 69 } 70 } 71 while(head!=tail) 72 { 73 int u = Q[head++]; 74 for(i = 0; i < child_num ; i++) 75 { 76 if(ch[u][i]) 77 { 78 Q[tail++] = ch[u][i]; 79 fail[ch[u][i]] = ch[fail[u]][i]; 80 } 81 else 82 ch[u][i] = ch[fail[u]][i]; 83 } 84 } 85 } 86 void work(char *s) 87 { 88 int i,k = strlen(s); 89 memset(f,0,sizeof(f)); 90 int p = 0; 91 for(i = 0 ;i < k ; i++) 92 { 93 int d = id[s[i]]; 94 p = ch[p][d]; 95 int tmp = p; 96 while(tmp!=0&&(val[tmp]!=0||f[val[tmp]])) 97 { 98 if(!f[val[tmp]]) 99 o[g++] = val[tmp]; 100 f[val[tmp]] = 1; 101 tmp = fail[tmp]; 102 } 103 } 104 } 105 }ac; 106 int main() 107 { 108 int n,m,i; 109 char vir[210]; 110 ac.init(); 111 while(scanf("%d%*c",&n)!=EOF) 112 { 113 ac.reset(); 114 for(i = 1; i <= n; i++) 115 { 116 gets(vir); 117 ac.insert(vir,i); 118 } 119 scanf("%d%*c",&m); 120 int ans = 0; 121 ac.construct(); 122 for(i = 1; i <= m ;i++) 123 { 124 gets(s); g = 0 ; 125 ac.work(s); 126 if(g==0) continue; 127 printf("web %d:",i); 128 sort(o,o+g); 129 for(int j = 0 ;j < g ; j++) 130 printf(" %d",o[j]); 131 puts(""); 132 ans++; 133 } 134 printf("total: %d ",ans); 135 } 136 return 0; 137 }