[HDU2896]病毒侵袭(AC自动机)
AC自动机直接匹配
Code
#include <cstdio> #include <algorithm> #include <cstring> #define M 130 #define N 100010 using namespace std; char s[N/10]; int n,m,T[N][M],fail[N],num=1,mark[N],q[N],tot; bool used[520]; void Insert(int x){ int len=strlen(s),now=1; for(int i=0;i<len;++i){ if(!T[now][s[i]]) T[now][s[i]]=++num; now=T[now][s[i]]; } mark[now]=x; } void getfail(){ for(int i=0;i<128;++i) T[0][i]=1; int k,now,h=0,t=0;q[++t]=1; while(h<t){ now=q[++h]; for(int i=0;i<128;++i) if(T[now][i]){ k=fail[now]; while(!T[k][i]) k=fail[k]; fail[q[++t]=T[now][i]]=T[k][i]; }else T[now][i]=T[fail[now]][i]; } } bool match(int x){ int res=0,len=strlen(s),now=1; bool flag=0; memset(used,0,sizeof(used)); for(int i=0;i<len;++i){ now=T[now][s[i]]; for(int tmp=now;tmp!=1;tmp=fail[tmp]) if(mark[tmp]){ used[mark[tmp]]=1; flag=1; } } if(!flag) return 0; printf("web %d:",x); for(int i=1;i<=n;++i) if(used[i]) printf(" %d",i); puts(""); return 1; } int main(){ scanf("%d",&n); for(int i=1;i<=n;++i){scanf("%s",s);Insert(i);} getfail(); scanf("%d",&m); for(int i=1;i<=m;++i){ scanf("%s",s); if(match(i)) tot++; } printf("total: %d\n",tot); return 0; }