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

猜你喜欢

转载自www.cnblogs.com/void-f/p/8981875.html
今日推荐