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;
}