[模板]AC自动机(2)
题目描述
求出现在文本串中最多的模式串
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 1000005
int N;
char s[155][100];
char T[MAXN];
int len;
struct queue{
int que[MAXN];int head,tail;
inline void clear(){head = 1;tail = 0;}
inline void pop(){head++;}
inline int front(){return que[head];}
inline void push(int x){que[++tail]=x;}
inline bool empty(){return head>tail;}
}q;
struct Node{
int val,num;
};
struct Auto{
int trie[26][MAXN];Node rec[MAXN];int fail[MAXN];int tot;int count[MAXN];
inline void clear(){
std::memset(trie,0,sizeof(trie));
std::memset(rec,0,sizeof(rec));
std::memset(count,0,sizeof(count));
tot = 0;
}
inline void ins(int x){
int _next = 0;len = std::strlen(s[x]);
for(register int i=0;i<len;++i){
int c = s[x][i]-'a';
if(!trie[c][_next])trie[c][_next]=++tot;
_next = trie[c][_next];
}
rec[_next].val++;
rec[_next].num = x;
}
inline void make_fail(){
for(register int i=0;i<26;++i){
if(trie[i][0]){
q.push(trie[i][0]);
fail[trie[i][0]] = 0;
}
}
while(!q.empty()){
int u = q.front();q.pop();
for(register int i=0;i<26;++i){
if(trie[i][u]){
q.push(trie[i][u]);
fail[trie[i][u]] = trie[i][fail[u]];
}
else trie[i][u] = trie[i][fail[u]];
}
}
}
inline void find(){
int _next = 0;len = std::strlen(T);
for(register int i=0;i<len;++i){
_next = trie[T[i]-'a'][_next];
for(register int j=_next;j;j=fail[j]){
if(rec[j].val)count[rec[j].num]++;
}
}
}
}AC;
int ans[MAXN];
int main(){
while((scanf("%d\n",&N))&&N>0){
AC.clear();
q.clear();
for(register int i=1;i<=N;++i){
scanf("%s",s[i]);
AC.ins(i);
}
AC.make_fail();
scanf("%s",T);
AC.find();
int maxx = 0;
int pos = 0;
for(register int i=1;i<=N;++i){
if(maxx<AC.count[i]){
maxx = AC.count[i];
ans[1]=i;
pos = 1;
}
else if(maxx==AC.count[i])ans[++pos] = i;
}
printf("%d\n",maxx);
for(register int i=1;i<=pos;++i)puts(s[ans[i]]);
}
return 0;
}