病毒侵袭持续中
题目大意:病毒侵袭的续集,也是AC自动机,区别就是许多匹配串换成了一个长串,并且记录一下病毒出现的次数即可。
Code:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#define inf 0x3f3f3f3f
#define ll long long
#define INT 9654234
using namespace std;
const int maxn = 500005; //数组大小 50(字符串长度) *1000(字符串个数) -> 500005
int vis[maxn];
struct Trie{
int next[maxn][128],fail[maxn],end[maxn],size[maxn];
int root,l;
int newnode(){
for(int i=0;i<128;i++) next[l][i]=-1;
end[l++]=0;
return l-1;
}
void init(){
l=0;
memset(size,0,sizeof size);
memset(vis,0,sizeof vis);
root =newnode();
}
void insert(char buf[],int x){
int len=strlen(buf);
int now=root;
for(int i=0;i<len;i++){
if(next[now][buf[i]]==-1)
next[now][buf[i]]=newnode();
now=next[now][buf[i]];
}
size[now]=x;
}
void bulid(){
queue<int> q;
fail[root]=root;
for(int i=0;i<128;i++){
if(next[root][i]==-1) next[root][i]=root;
else {
fail[next[root][i]]=root;
q.push(next[root][i]);
}
}
while(!q.empty()){
int now= q.front();
q.pop();
for(int i=0;i<128;i++){
if(next[now][i]==-1) next[now][i]=next[fail[now]][i];
else{
fail[next[now][i]]=next[fail[now]][i];
q.push(next[now][i]);
}
}
}
}
void query(char buf[]){
int len=strlen(buf);
int now=root;
int res=0,flag=0;
for(int i=0;i<len;i++){
now=next[now][buf[i]];
for(int tmp=now;tmp;tmp=fail[tmp]){
if(size[tmp]){
vis[size[tmp]]++; //记录出现的次数
}
}
}
}
} ac;
char buf[1002][60],str[2000007];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int T,n,m;
while(scanf("%d",&n)==1&&n){
int all=0;
ac.init();
for(int i=1;i<=n;i++){
scanf("%s",&buf[i]);
ac.insert(buf[i],i);
}
ac.bulid();
scanf("%s",&str);
ac.query(str);
for(int i=1;i<=n;i++){
if(vis[i]) printf("%s: %d\n",buf[i],vis[i]);
}
}
return 0;
}