AC自动机模板
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<queue> #include<algorithm> using namespace std; const int maxn=1e6+50; int n; char str[500][500]; char qry[maxn]; struct Auto_AC { int tr[maxn][26],val[maxn],fail[maxn],cnt[maxn],fa[maxn]; int Size; inline void init() { Size=0; memset(val,0,sizeof(val)); memset(fail,0,sizeof(fail)); memset(cnt,0,sizeof(cnt)); memset(fa,0,sizeof(fa)); memset(tr,0,sizeof(tr)); } inline void add(char s[],int ind) { int now=0,k,len=strlen(s); for(int i=0;i<len;i++) { k=s[i]-'a'; if(!tr[now][k])tr[now][k]=++Size; now=tr[now][k]; } val[now]=ind; } inline void makefail() { queue<int> q; q.push(0); int now,k,v; while(!q.empty()) { now=q.front();k=fa[now];q.pop(); for(int cc=0;cc<=25;cc++) { v=tr[now][cc]; if(!v){tr[now][cc]=tr[k][cc];continue;} fa[v]=now ? tr[k][cc] : 0; fail[v]=val[fa[v]]?fa[v]:fail[fa[v]]; q.push(v); } } } inline void query(char s[]) { int now=0,len=strlen(s),ans=0,k,v; for(int i=0;i<len;i++) { k=s[i]-'a'; now=tr[now][k]; if(val[now])cnt[val[now]]++; v=fail[now]; while(v) { if(val[v])cnt[val[v]]++; v=fail[v]; } } for(int i=1;i<=n;i++)ans=max(ans,cnt[i]); printf("%d\n",ans); for(int i=1;i<=n;i++)if(cnt[i]==ans)printf("%s\n",str[i]); } }Machine; int main() { while(scanf("%d",&n) && n) { Machine.init(); for(int i=1;i<=n;i++) { scanf("%s",str[i]); Machine.add(str[i],i); } Machine.makefail(); scanf("%s",qry); Machine.query(qry); } }
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<queue> #include<algorithm> using namespace std; const int maxn=500010; int n; char str[1000005]; char qry[1000005]; struct Auto_AC { int tr[maxn][26],val[maxn],fail[maxn],cnt[maxn],fa[maxn]; int Size; inline void init() { Size=0; memset(val,0,sizeof(val)); memset(fail,0,sizeof(fail)); memset(cnt,0,sizeof(cnt)); memset(fa,0,sizeof(fa)); memset(tr,0,sizeof(tr)); } inline void add(char s[]) { int now=0,k,len=strlen(s); for(int i=0;i<len;i++) { k=s[i]-'a'; if(!tr[now][k])tr[now][k]=++Size; now=tr[now][k]; } val[now]++; } inline void makefail() { queue<int> q; q.push(0); int now,k,v; while(!q.empty()) { now=q.front();k=fa[now];q.pop(); for(int cc=0;cc<=25;cc++) { v=tr[now][cc]; if(!v){tr[now][cc]=tr[k][cc];continue;} fa[v]=now ? tr[k][cc] : 0; fail[v]=val[fa[v]]?fa[v]:fail[fa[v]]; q.push(v); } } } inline int query(char s[]) { int now=0,len=strlen(s),ans=0,k,v; for(int i=0;i<len;i++) { k=s[i]-'a';now=tr[now][k]; for(int t=now;t && ~val[t];t=fail[t])ans+=val[t],val[t]=-1; } return ans; } }Machine; int main() { scanf("%d",&n); //Machine.init(); for(int i=1;i<=n;i++) { scanf("%s",str); Machine.add(str); } Machine.makefail(); scanf("%s",qry); cout<<Machine.query(qry); }