代码:
#include <cstdio>
#include <cstring>
#include <queue>
#define MAXN 1000010
using namespace std;
int q[MAXN];
int ascii[256];
struct Trie{
int child[MAXN][26],fail[MAXN];
bool mark[MAXN];
int root,L;
int newnode(){
for(int i=0;i<26;++i) child[L][i]=-1;
mark[L++]=false;
return L-1;
}
void init(){
L=0;
root=newnode();
}
void insertnode(const char* str){
int len=strlen(str);
int now=root;
for(int i=0;i<len;++i){
if(child[now][ascii[str[i]]]==-1)
child[now][ascii[str[i]]]=newnode();
now=child[now][ascii[str[i]]];
}
mark[now]=true;
}
void build(){
fail[root]=root;
int top,tail;
top=tail=0;
for(int i=0;i<26;++i){
if(child[root][i]==-1)
child[root][i]=root;
else{
fail[child[root][i]]=root;
q[tail++]=child[root][i];
}
}
while(top<tail){
int now=q[top++];
if(mark[fail[now]])///优化1,不然超时
mark[now]=true;
for(int i=0;i<26;++i){
if(child[now][i]==-1)
child[now][i]=child[fail[now]][i];
else{
fail[child[now][i]]=child[fail[now]][i];
q[tail++]=child[now][i];
}
}
}
}
bool query(const char* str){
int len=strlen(str);
int now=root;
for(int i=0;i<len;++i){
now=child[now][ascii[str[i]]];
if(mark[now]) return true;
}
return false;
}
}tr;
char st[MAXN];
int main(){
for(int i=0;i<26;++i)
ascii['a'+i]=i;
int n;
scanf("%d",&n);
tr.init();
while(n--){
scanf("%s",st);
tr.insertnode(st);
}
tr.build();
scanf("%s",st);
if(tr.query(st))
printf("YES\n");
else
printf("NO\n");
return 0;
}