坑爹的题意...明明说了第一行怎么怎么..接下来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; }