AC自动机2
给N个模式串,求文本串中出现次数最多的模式串出现次数。
#include<bits/stdc++.h> using namespace std; #define maxn 1000005 #define maxm 28 struct AC { int trieN; int ch[maxn][maxm]; int val[maxn]; int fail[maxn]; int s[maxn]; int tim[maxn]; void init() { trieN=-1; newnod(); } int newnod() { memset(ch[++trieN],0,sizeof ch[0]); val[trieN]=fail[trieN]=0; tim[trieN]=s[trieN]=0; return trieN; } void insert(const string & str,int k) { int cur=0; for(int i=0; i<str.size(); i++) { int d=str[i]-'a'; if(!ch[cur][d]) { ch[cur][d]=newnod(); } cur=ch[cur][d]; } val[cur]++; s[cur]=k; } void build() { queue<int> q; for(int i=0; i<maxm; i++) { if(ch[0][i]) { q.push(ch[0][i]); } } while(!q.empty()) { int cur=q.front(); q.pop(); for(int i=0; i<maxm; i++) { if(ch[cur][i]) { fail[ch[cur][i]]=ch[fail[cur]][i]; q.push(ch[cur][i]); } else { ch[cur][i]=ch[fail[cur]][i]; } } } } vector<int>ans; int man=0; void query(const string & str) { ans.clear(); man=0; int res=0,cur=0; for(int i=0; str[i]; i++) { int d=str[i]-'a'; cur=ch[cur][d]; int tmp=cur; // int si=0; //cout<<tmp<<'\n'; while(tmp&&val[tmp]>=0) { res=val[tmp]; if(val[tmp]) { tim[tmp]++; if(tim[tmp]>man) { man=tim[tmp]; ans.clear(); for(int _i=0; _i<res; _i++) ans.push_back(s[tmp]); } else if(man==tim[tmp]) { for(int _i=0; _i<res; _i++) ans.push_back(s[tmp]); } } //val[tmp]=-1; tmp=fail[tmp]; } } } } ac; string A[maxn]; int main() { string s; int n; while(scanf("%d",&n)) { ac.init(); if(n==0)break; for(int i=0; i<n; i++) { cin>>A[i]; ac.insert(A[i],i); } ac.build(); cin>>s; ac.query(s); cout<<ac.man<<'\n'; sort(ac.ans.begin(),ac.ans.end()); for(int i=0; i<ac.ans.size(); i++) { cout<<A[ac.ans[i]]<<'\n'; } } }