坑爹的题意...明明说了第一行怎么怎么..接下来N行怎么怎么...搞半天是多组Case..这不忽悠人么!!

       先用病毒传构造AC自动机..再遍历网站源码...当走到一点,从这点不断fail直到头接点..路径上所有点的经过次数++..


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[26],fail,w;
}point[50005];
int n,a[1003],g,had[50005];
char s[2000005],str[1002][52];
queue<int> myqueue;
int main()
{
int h,k,len,i,t,ans,num;
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
while (~scanf("%d",&n))
{
num=0;
memset(point,0,sizeof(point));
memset(a,0,sizeof(a));
for (t=1;t<=n;t++)
{
scanf("%s",str[t]);
len=strlen(str[t]);
h=0;
for (i=0;i<len;i++)
{
if (!point[h].son[str[t][i]-'A'])
point[h].son[str[t][i]-'A']=++num;
h=point[h].son[str[t][i]-'A'];
}
point[h].w=t;
a[t]=h;
}
while (!myqueue.empty()) myqueue.pop();
for (i=0;i<26;i++)
if (point[0].son[i]) myqueue.push(point[0].son[i]);
while (!myqueue.empty())
{
h=myqueue.front();
myqueue.pop();
for (i=0;i<26;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]);
}
}
ans=0;
memset(had,0,sizeof(had));
scanf("%s",s);
len=strlen(s);
h=0;
for (i=0;i<len;i++)
{
if (s[i]>='A' && s[i]<='Z')
h=point[h].son[s[i]-'A'];
else h=0;
k=h;
while (k)
{
had[k]++;
k=point[k].fail;
}
}
for (t=1;t<=n;t++)
if (had[a[t]])
printf("%s: %d\n",str[t],had[a[t]]);
}
return 0;
}