洛谷P3808 【模板】AC自动机(简单版)
Code:
#include<cstdio> //Aho Corasick Automaton
#include<cstring>
#include<queue>
using namespace std;
const int maxn=1000000+3;
const int maxd=20000+3;
const int sigma=30;
char S[maxn],A[160][80];
int mapp[152],times[maxd],val[maxd],last[maxd],f[maxd];
int cnt=0,ans;
queue<int>Q;
struct node{int next[30];}ch[maxd];
int idx(char a){return a-'a';}
struct V{
void insert(char p[],int id){
int n=strlen(p),cur=0;
for(int i=0;i<n;++i){
int u=idx(p[i]);
if(!ch[cur].next[u])ch[cur].next[u]=++cnt;
cur=ch[cur].next[u];
}
++val[cur],mapp[id]=cur;
}
void getfail(){
for(int i=0;i<sigma;++i)if(ch[0].next[i])Q.push(ch[0].next[i]);
while(!Q.empty()){
int r=Q.front(); Q.pop();
for(int i=0;i<sigma;++i){
int u=ch[r].next[i];
if(!u){ch[r].next[i]=ch[f[r]].next[i];continue;}
Q.push(u);v=f[r];
f[u]=ch[v].next[i];
last[u]=val[f[u]]?f[u]:last[f[u]];
}
}
}
void print(int j){
if(j){
if(val[j]){++times[j];ans=max(ans,times[j]);}
if(last[j]){
print(last[j]);
}
}
}
void Automaton(char T[]){
int n=strlen(T);int j=0;
for(int i=0;i<n;++i){
int c=idx(T[i]);
j=ch[j].next[c];
print(j);
}
}
}AC;
int main(){
while(1){
int n;scanf("%d",&n);if(!n)return 0;
memset(ch,0,sizeof(ch));
memset(val,0,sizeof(val));
memset(last,0,sizeof(last));
memset(f,0,sizeof(f));
memset(times,0,sizeof(times));
cnt=0,ans=0;
for(int i=1;i<=n;++i){scanf("%s",A[i]);AC.insert(A[i],i);}
scanf("%s",S);
AC.getfail();
AC.Automaton(S);
printf("%d\n",ans);
for(int i=1;i<=n;++i)
if(times[mapp[i]]==ans)printf("%s\n",A[i]);
}
return 0;
}