Input
第一行为一个整数n,表示文本的长度
第二行为一个长度为n的文本
第三行为一个整数m,表示模式串个数
下接m行,每行一个模式串
Output
共m行,若第i个模式串在文本中出现过则第i行输出YES,否则输出NO
数据范围
对于30%的数据,n<=10^3,m<=10^3;
对于80%的数据,n<=10^5,m<=10^4;
对于100%的数据,n<=10^5,m<=10^5。
输入文件大小不超过1M。
Sample Input
25
saintzeuscynthiathenahere
3
cynthia
hera
athena
Sample Output
YES
NO
YES
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e6+10;
struct Trie{
int son[26];
int cnt;
int fail;
}AC[MAXN];
int n,m,tot=0,iidd[MAXN];
bool ans[MAXN];
char S[MAXN],T[MAXN];
void add(char *s,int len,int id){
int now=0;
for(register int i=0;i<len;i++){
if(!AC[now].son[s[i]-‘a‘]) AC[now].son[s[i]-‘a‘]=++tot;
now=AC[now].son[s[i]-‘a‘];
}
if(AC[now].cnt) iidd[id]=AC[now].cnt;
else AC[now].cnt=id;
}
void get_fail(){
queue<int> q;
AC[0].fail=0;
for(register int i=0;i<26;i++){
if(AC[0].son[i]){
AC[AC[0].son[i]].fail=0;
q.push(AC[0].son[i]);
}
}
while(!q.empty()){
int u=q.front();
q.pop();
for(register int i=0;i<26;i++)
{
if(AC[u].son[i])
{
AC[AC[u].son[i]].fail=AC[AC[u].fail].son[i];
q.push(AC[u].son[i]);
}
else
AC[u].son[i]=AC[AC[u].fail].son[i];
}
}
}
void AC_query(char *s,int len){
int now=0;
for(register int i=0;i<len;i++)
{
now=AC[now].son[s[i]-‘a‘];
for(register int t=now;t;t=AC[t].fail)
{
if(AC[t].cnt&&ans[AC[t].cnt]) break;
ans[AC[t].cnt]=true;
}
}
}
int main(){
scanf("%d",&n);
scanf("%s",S);
scanf("%d",&m);
for(register int i=1;i<=m;i++) iidd[i]=i;
for(register int i=1;i<=m;i++){
scanf("%s",T);
add(T,strlen(T),i);
}
get_fail();
AC_query(S,n);
for(register int i=1;i<=m;i++){
if(ans[iidd[i]]) printf("YES\n");
else printf("NO\n");
}
return 0;
}
原文:https://www.cnblogs.com/cutemush/p/12268210.html