HDU2896病毒入侵AC_自动机
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 130; struct node{ bool flg; int id; node *next[maxn],*fail; void Node(){ fail = NULL; flg = false; memset(next,NULL,sizeof(next)); } }arr[500000],*que[500000]; int vis[505],num[10],cnt; char str[10000]; void insert(int num,char *str){ node *p = &arr[0]; while( *str ){ int k = *str++ - 31; if( !p->next[k]){ arr[++cnt].Node(); p->next[k] = &arr[cnt]; } p = p->next[k]; } p->flg = true; p->id = num; } void build_AC(){ node *root = &arr[0],*tmp,*p; int head = 0,tail = 0; for(int i = 0; i < maxn; i++){ if( !root->next[i] )continue; root->next[i]->fail = root; que[head++] = root->next[i]; } while( head != tail){ tmp = que[tail++]; for(int i = 0; i < maxn; i++){ if( !tmp->next[i] )continue; p = tmp->fail; while( p ){ if( p->next[i]){ tmp->next[i]->fail = p->next[i]; break; } p = p->fail; } if(!p)tmp->next[i]->fail = root; que[head++] = tmp->next[i]; } } } int query(char *str){ int ans = 0; node *p = &arr[0],*root = &arr[0]; while( *str ){ int k = *str++ - 31; while( !p->next[k] && p != root)p = p->fail; p = p->next[k]; p = p ? p : root; node *tmp = p; while( tmp != root && !vis[tmp->id]){ if( tmp->flg && !vis[tmp->id] ){ vis[tmp->id] = 1; num[ans++] = tmp->id; } tmp = tmp->fail; } } return ans; } int main(){ int n; char ch[205]; while( ~scanf("%d",&n)){ for(int i = 1; i <= n; i++){ scanf("%s",ch); insert(i,ch); } int total = 0; build_AC(); scanf("%d",&n); for(int i = 1; i <= n; i++){ scanf("%s",str); memset(vis,0,sizeof(vis)); int ans = query(str); if( ans ){ total ++; sort(num,num+ans); printf("web %d:",i); for(int j = 0; j < ans; j++){ printf(" %d",num[j]); } puts(""); } } printf("total: %d\n",total); } return 0; }