http://www.elijahqi.win/2017/07/07/hdu2896/
现在ac自动机早就忘干净了 题解回来补 待填坑
update:
题意:给定一些病毒串
再给定一些网站串 求每个网站串里都包含多少个病毒 分别是谁
那么 针对病毒建AC自动机 然后每次把网站去AC自动机上跑
跑到一个病毒就跳fail看我后缀是否也是病毒 记录即可
#include<cstdio>
#include<cstring>
int n,m;bool ans[550];
char str1[220],str2[11000];
struct node{
int word,id;
node *next[129],*fail;
node(){
id=0;
for (int i=1;i<=128;++i) next[i]=NULL;
fail=NULL;
}
};
node *root;
void insert1(char s[],int x){
int l=strlen(s);
node *p=root;
for (int i=0;i<l;++i){
int xx=s[i];
if (p->next[xx]==NULL) p->next[xx]=new node();
p=p->next[xx];
}
p->id=x;
}
node *d[550];
void fail1(){
int op=-1,cl=0;
d[cl]=root;
while (op<cl){
node *p=d[(++op)%500];
//printf("11111\n");
//printf("%d %d\n",op,cl);
for (int i=1;i<=128;++i){
if (p->next[i]!=NULL){
d[(++cl)%500]=p->next[i];
node *p1=p->fail;
while (p1!=NULL&&p1->next[i]==NULL) {
p1=p1->fail; //printf("sss");
}
if (p1==NULL){
p->next[i]->fail=root;
}else{
p->next[i]->fail=p1->next[i];
}
}
}
}
}
void query(char s[]){
node *p=root;
int l=strlen(s);
for (int i=0;i<l;++i){
int x=s[i];
while (p!=NULL&&p->next[x]==NULL) p=p->fail;
if (p==NULL){
p=root;continue;
}
p=p->next[x];
node *p1=p;
while (p1!=NULL){
if (p1->id!=0){
ans[p1->id]=true;
}
p1=p1->fail;
}
}
}
int check(){
for (int i=1;i<=n;++i) {
if (ans[i]==true) return 1;
}
return 0;
}
int main(){
freopen("hdu2896.in","r",stdin);
freopen("hdu2896.out","w",stdout);
scanf("%d",&n);
root = new node();
for (int i=1;i<=n;++i) {
scanf("%s",str1);
insert1(str1,i);
}
fail1();
//printf("dddd");
scanf("%d",&m);
int anss=0;
for (int i=1;i<=m;++i) {
scanf("%s",str2);
memset(ans,false,sizeof(ans));
query(str2);
if (check()!=0){
printf("web %d:",i);
for (int i=1;i<=n;++i){
if (ans[i]==true) {
printf(" %d",i);
}
}
anss++;
printf("\n");
}
//for (int i=1;i<=n;++i) printf("%d ",ans[i]);
}
printf("total: %d\n",anss);
return 0;
}