对sha崽AC自动机专项练习的扫尾...本题确实是比较卡空间啊...我是试次空间了几次才过的...囧..
这里的ASCII码是0~127的...用病毒传构造AC自动机..进一步构造Trie图...再通过Trie图遍历所有网站编号..记录统计即可..
Program:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#define oo 2000000000
#define ll long long
using namespace std;
struct node
{
int son[128],fail;
int w;
}point[60001];
int n,m,a[503],g;
bool had[60001];
char s[10003];
queue<int> myqueue;
int main()
{
int h,k,len,i,t,ans,num=0;
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d",&n);
memset(point,0,sizeof(point));
for (t=1;t<=n;t++)
{
scanf("%s",s);
len=strlen(s);
h=0;
for (i=0;i<len;i++)
{
if (!point[h].son[s[i]]) point[h].son[s[i]]=++num;
h=point[h].son[s[i]];
}
point[h].w=t;
}
while (!myqueue.empty()) myqueue.pop();
for (i=0;i<128;i++)
if (point[0].son[i]) myqueue.push(point[0].son[i]);
while (!myqueue.empty())
{
h=myqueue.front();
myqueue.pop();
for (i=0;i<128;i++)
{
k=point[h].fail;
while (k && !point[k].son[i]) k=point[k].fail;
point[point[h].son[i]].fail=point[k].son[i];
if (!point[h].son[i])
point[h].son[i]=point[k].son[i];
else
myqueue.push(point[h].son[i]);
}
}
scanf("%d",&m);
ans=0;
for (t=1;t<=m;t++)
{
scanf("%s",s);
len=strlen(s);
memset(had,false,sizeof(had));
h=0;
for (i=0;i<len;i++)
{
h=point[h].son[s[i]];
k=h;
while (k && !had[k])
{
had[k]=true;
k=point[k].fail;
}
}
g=0;
for (i=0;i<=num;i++)
if (had[i] && point[i].w) a[++g]=point[i].w;
if (g)
{
ans++;
printf("web %d:",t);
for (i=1;i<=g;i++) printf(" %d",a[i]);
printf("\n");
}
}
printf("total: %d\n",ans);
return 0;
}