Link:http://hihocoder.com/problemset/problem/1036?sid=1157591
// 需要優化
#include <bits/stdc++.h>
using namespace std;
const int N = 1000110;
const int M = 26;
const int root = 0;
int n,len[N];
struct Aho
{
struct Node{
int nex[M];
int fail,endd;
}node[N];
int Size;
queue<int> que;
int newnode(){
for(int i = 0; i < M; i++)
node[Size].nex[i] = 0;
node[Size].fail = node[Size].endd = 0;
return Size++;
}
void init(){
while(que.size()) que.pop();
Size = root;
newnode();
}
void Insert(char *s)
{
int L = strlen(s);
int now = root;
for(int i = 0; i < L; i++){
int x = s[i]-'a';
if(node[now].nex[x]==0)
node[now].nex[x]=newnode();
now = node[now].nex[x];
}
node[now].endd = 1;
}
void build()
{
node[root].fail = root;
for(int i = 0; i < M; i++)
{
if(node[root].nex[i])
{
node[node[root].nex[i]].fail = root;
que.push(node[root].nex[i]);
}
}
while(que.size())
{
int u = que.front();
que.pop();
for(int i = 0; i < M; i++)
{
if(node[u].nex[i]==0)
node[u].nex[i] = node[node[u].fail].nex[i];
else
{
node[node[u].nex[i]].fail = node[node[u].fail].nex[i];
que.push(node[u].nex[i]);
if(node[node[node[u].nex[i]].fail].endd)
node[node[u].nex[i]].endd = 1;
//優化,與普通的AC自動機不同,因爲只要有河蟹詞就返回,所以有河蟹詞後綴的也標記危險,去掉查詢時通過while查詢後綴
}
}
}
}
int marth(char *s)
{
int L = strlen(s);
int now = root;
for(int i = 0; i < L; i++)
{
int x = s[i]-'a';
now = node[now].nex[x];
if(node[now].endd)
return 1;
}
return 0;
}
}aho;
char s[N];
int main()
{
int n;
scanf("%d",&n);
aho.init();
for(int i = 0; i < n; i++)
{
scanf("%s",s);
aho.Insert(s);
}
aho.build();
scanf("%s",s);
if(aho.marth(s))
puts("YES");
else
puts("NO");
}