AC自动机的裸题。虽然是水题却做了很久,居然在每次查询的脑残的去修改字典树的信息。
还有数组开小了居然会返回wa。。。
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<queue> 5 #include<algorithm> 6 using namespace std; 7 const int maxn=85010; 8 const int sig=100; 9 int ch[maxn][sig],last[maxn],f[maxn],num,cnt,top,n,m,val[maxn],vis[10000]; 10 char p[maxn]; 11 12 void init() 13 { 14 top=1; 15 num=0; 16 memset(ch[0],0,sizeof(ch)); 17 memset(f,0,sizeof(f)); 18 } 19 20 int idx(char c) 21 { 22 return c-' '; 23 } 24 void insert(char *s,int v) 25 { 26 int u=0,n=strlen(s); 27 for(int i=0;i<n;i++) 28 { 29 int c=idx(s[i]); 30 if(!ch[u][c]) 31 { 32 memset(ch[top],0,sizeof(ch[top])); 33 val[top]=0; 34 ch[u][c]=top++; 35 } 36 u=ch[u][c]; 37 } 38 val[u]=v; 39 } 40 41 void getfail() 42 { 43 queue<int> q; 44 f[0]=0; 45 int c,u; 46 for(c=0;c<sig;c++) 47 { 48 u=ch[0][c]; 49 if(u){f[u]=0;q.push(u);last[u]=0;} 50 } 51 int r,v; 52 while(!q.empty()) 53 { 54 r=q.front();q.pop(); 55 for(c=0;c<sig;c++) 56 { 57 u=ch[r][c]; 58 if(!u) {ch[r][c]=ch[f[r]][c];continue;} 59 q.push(u); 60 v=f[r]; 61 f[u]=ch[v][c]; 62 last[u]=val[last[u]]?f[u]:last[f[u]]; 63 } 64 } 65 } 66 67 void print(int j) 68 { 69 if(j) 70 { 71 if(cnt==0) 72 { 73 vis[val[j]]=1; 74 cnt++; 75 num++; 76 } 77 else 78 vis[val[j]]=1; 79 print(last[j]); 80 } 81 } 82 void find(char *s,int v) 83 { 84 int n=strlen(s),i; 85 int j=0,c; 86 cnt=0; 87 memset(vis,0,sizeof(vis)); 88 for(i=0;i<n;i++) 89 { 90 c=idx(s[i]); 91 while(j&&!ch[j][c]) j=f[j]; 92 j=ch[j][c]; 93 if(val[j]) print(j); 94 else if(last[j]) print(last[j]); 95 } 96 97 if(cnt) 98 { 99 printf("web %d:",v); 100 for(i=1;i<=n;i++) 101 { 102 if(vis[i]) 103 printf(" %d",i); 104 } 105 printf("\n"); 106 } 107 } 108 int main() 109 { 110 //freopen("test.txt","r",stdin); 111 scanf("%d",&n); 112 int i,j; 113 for(i=0;i<n;i++) 114 { 115 scanf("%s",p); 116 insert(p,i+1); 117 } 118 getfail(); 119 scanf("%d",&m); 120 for(i=0;i<m;i++) 121 { 122 scanf("%s",p); 123 find(p,i+1); 124 } 125 printf("total: %d\n",num); 126 return 0; 127 }