#include<bits/stdc++.h> using namespace std; const int maxn=1e6+7; char tex[maxn]; char pat[maxn]; int tr[maxn][28]; int val[maxn]; int fail[maxn]; bool vis[maxn]; int n,q; int rt,tot=1; int len; void Trie(int x){ rt=1; for(int i=0;i<len;i++){ int c=pat[i]-‘a‘; if(!tr[rt][c]) tr[rt][c]=++tot; rt=tr[rt][c]; } val[x]=rt;//每个串结尾打上标记 } queue<int> que; void AC(){ for(int i=0;i<26;i++) tr[0][i]=1; que.push(1); fail[1]=0; while(!que.empty()){ int u=que.front(); que.pop(); for(int i=0;i<26;i++){ if(tr[u][i]){ fail[tr[u][i]]=tr[fail[u]][i]; que.push(tr[u][i]); } else tr[u][i]=tr[fail[u]][i]; } } } void query(){ len=strlen(tex); rt=1; for(int i=0;i<len;i++){ int c=tex[i]-‘a‘; while(rt&&!tr[rt][c]) rt=fail[rt]; rt=tr[rt][c]; int k=rt; while(k&&!vis[k]){//是否被便利过 vis[k]=true; k=fail[k]; } } } int main(){ freopen("substring.in","r",stdin); freopen("substring.out","w",stdout); scanf("%d%d",&n,&q); scanf("%s",tex); for(int i=1;i<=q;i++){ scanf("%s",pat); len=strlen(pat); Trie(i); } AC(); query(); for(int i=1;i<=q;i++){ if(!vis[val[i]]){ printf("NO\n"); } else printf("YES\n"); } return 0; }
AC自动机的模板题,非常简单,但我对AC自动机的掌握都还不太熟练。
原文:https://www.cnblogs.com/LJB666/p/11191125.html