本来很简单的一道题目,和病毒侵袭差不多,只不过把bool ans 改成了int ans 然后统计一下次数就好了, 但是题目中居然没有出现多组数据的提示。。。。Wa了N次,居然因为没有多组数据。。。
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <iostream>
using namespace std;
#define rep(i,k) for(int (i)=1;(i)<=(k);(i)++)
const int MAXN = 1000;
struct State{
int fail, flag;
int ch[26];
}p[MAXN*50+30];
int scnt, Bef[MAXN*50+30];
void Add(char *s, int id){
int now = 0, len = strlen(s);
for(int i=0;i<len;i++){
if(!p[now].ch[s[i]-'A'])
p[now].ch[s[i]-'A'] = ++scnt;
now = p[now].ch[s[i]-'A'];
}
p[now].flag = id;
}
void _initTree(){
queue<int> que;
for(int i=0;i<26;i++)
if(p[0].ch[i])
que.push(p[0].ch[i]);
while(!que.empty()){
int u = que.front();
que.pop();
for(int i=0;i<26;i++) if(p[u].ch[i]){
int v = p[u].ch[i];
que.push(v);
int k = p[u].fail;
while(k && !p[k].ch[i]) k = p[k].fail;
p[v].fail = p[k].ch[i];
Bef[v] = p[p[v].fail].flag > 0 ? p[v].fail : Bef[p[v].fail];
}
}
}
char ls[2000010];
int ans[MAXN+20];
void match(){
int len = strlen(ls);
int u = 0, ids;
memset(ans, 0, sizeof ans);
for(int i=0;i<len;i++){
if(ls[i] < 'A' || ls[i] > 'Z'){
u = 0;
continue;
}
ids = ls[i] - 'A';
if(p[u].ch[ids])
u = p[u].ch[ids];
else{
int k = p[u].fail;
while(k && !p[k].ch[ids]) k = p[k].fail;
u = p[k].ch[ids];
}
int k = u;
while(k){
if(p[k].flag)
ans[p[k].flag]++;
k = Bef[k];
}
}
}
char s[MAXN+10][60];
void _init(int n){
for(int i=0;i<=n;i++){
ans[i] = 0;
p[i].flag = p[i].fail = 0;
memset(p[i].ch, 0, sizeof p[i].ch);
}
memset(Bef, 0, sizeof Bef);
scnt=0;
}
int main(){
int T;
while(scanf("%d", &T) != EOF){
_init(T*50+10);
rep(i, T){
scanf("%s", s[i]);
Add(s[i], i);
}
_initTree();
scanf("%s", ls);
match();
rep(i, T){
if(!ans[i]) continue;
printf("%s: %d\n", s[i], ans[i]);
}
}
return 0;
}