P3796 【模板】AC自动机(加强版)
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> using namespace std; const int N=1e6+5; const int M=2e4; int n; char t[N],p[155][75]; int nxt[M][26]; int id[M],fail[M],last[M]; int now_node; struct ANS { int id,cnt; bool operator < (const ANS &A) const { return cnt==A.cnt?id<A.id:cnt>A.cnt; } }Ans[155]; void insert(char *s,int Id) { int len=strlen(s); int now=0,tmp; for(int i=0;i<len;++i) { tmp=s[i]-'a'; if(nxt[now][tmp]==0) nxt[now][tmp]=++now_node; now=nxt[now][tmp]; } id[now]=Id; return; } queue<int> que; void getfail() { for(int i=0;i<26;++i) { if(nxt[0][i]) { que.push(nxt[0][i]); } } int now,tmp; while(!que.empty()) { now=que.front(),que.pop(); for(int i=0;i<26;++i) { tmp=nxt[now][i]; if(tmp) { fail[tmp]=nxt[fail[now]][i]; last[tmp]=id[fail[tmp]]?fail[tmp]:last[fail[tmp]]; que.push(tmp); } else nxt[now][i]=nxt[fail[now]][i]; } } } void query(char *s) { int len=strlen(s); int now=0; for(int i=0;i<len;++i) { now=nxt[now][s[i]-'a']; for(int j=now;j;j=last[j]) ++Ans[id[j]].cnt; } } int main() { while(scanf("%d",&n)&&n!=0) { memset(nxt,0,sizeof(nxt)); for(int i=0;i<=now_node;++i) fail[i]=0,last[i]=0,id[i]=0; now_node=0; for(int i=1;i<=n;++i) { scanf("%s",p[i]); insert(p[i],i); Ans[i].id=i,Ans[i].cnt=0; } Ans[0].cnt=0; getfail(); scanf("%s",t); query(t); sort(Ans+1,Ans+n+1); cout<<Ans[1].cnt<<'\n'; for(int i=1;i<=n;++i) { puts(p[Ans[i].id]); if(Ans[i].cnt!=Ans[i+1].cnt) break; } } return 0; }