/*
洛谷 p3796
题意:n个模式串 一个文本串 问这个n个模式串最多的一个或者多个
出现在文本串里的个数 顺便输出这个最多的文本串
*/
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+1000;
int ans[N*10];
char s[N*10];
struct tire
{
int sz=0,ch[N][26],fail[N],num[N];
void Init(){
sz=0;
memset(ch,0,sizeof(ch));
memset(fail,0,sizeof(fail));
memset(num,0,sizeof(num));
memset(ans,0,sizeof(ans));
}
void Insert(char *s,int v){
int root=0;
int len=strlen(s);
for(int i=0;i<len;i++){
int t=s[i]-'a';
if(!ch[root][t]) ch[root][t]=++sz;
root=ch[root][t];
}
num[root]=v;//标记一下
//num[root]++ 出现多少次用的
}
void build(){
queue<int>Q;
for(int i=0;i<26;i++){
if(ch[0][i]){
Q.push(ch[0][i]);
fail[ch[0][i]]=0;
}
}
while(!Q.empty()){
int u=Q.front();
Q.pop();
for(int i=0;i<26;i++){
int t=ch[u][i];
if(t){
fail[t]=ch[fail[u]][i];
Q.push(t);
}
else ch[u][i]=ch[fail[u]][i];
}
}
}
void query(char *s){
int root=0;
int len=strlen(s);
for(int i=0;i<len;i++){
root=ch[root][s[i]-'a'];
for(int j=root;j;j=fail[j]){
ans[num[j]]++;
}
}
}
void debug(){
for(int i = 0;i <=sz;i++){
printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],num[i]);
for(int j = 0;j < 26;j++)
printf("%2d",ch[i][j]);
printf("]\n");
}
}
}ac;
char tt[200][100];
int main()
{
int n;
while(scanf("%d",&n)==1&&n){
ac.Init();
for(int i=1;i<=n;i++){
scanf("%s",tt[i]);
ac.Insert(tt[i],i);
}
ac.build();
scanf("%s",s);
ac.query(s);
int t=0;
for(int i=1;i<=n;i++){
if(ans[i]>t) t=ans[i];
}
printf("%d\n",t);
for(int i=1;i<=n;i++){
if(ans[i]==t){
printf("%s\n",tt[i]);
}
}
}
return 0;
}
ac自动机 模板
猜你喜欢
转载自blog.csdn.net/CC_1012/article/details/94720542
今日推荐
周排行