题目:http://acm.hdu.edu.cn/showproblem.php?pid=2222
题意:给你n个单词和一个字符串,问有多少个单词出现过
#include<bits/stdc++.h>
using namespace std;
const int N=500000+5;
struct p
{
int next[N][26];
int fail[N],cnt[N];
int tot,root;
int newnode()
{
for(int i=0;i<26;i++)
next[tot][i]=-1;
fail[tot]=-1;
cnt[tot]=0;
return tot++;
}
void init()
{
tot=0;
root=newnode();
}
void add(char *s)
{
int now=root;
int len=strlen(s);
for(int i=0;i<len;i++)
{
if (next[now][s[i]-'a']==-1) next[now][s[i]-'a']=newnode();
now=next[now][s[i]-'a'];
}
++cnt[now];
}
void build()
{
queue<int> que;
que.push(root);
while(!que.empty())
{
int now=que.front();
que.pop();
for(int i=0;i<26;i++)
{
if (next[now][i]==-1)
{
if (now==root) next[now][i]=root;
else next[now][i]=next[fail[now]][i];
}
else
{
if (now==root) fail[next[now][i]]=root;
else fail[next[now][i]]=next[fail[now]][i];
que.push(next[now][i]);
}
}
}
}
int match(char *s)
{
int now=root,ans=0;
int len=strlen(s);
for(int i=0;i<len;i++)
{
now=next[now][s[i]-'a'];
for(int t=now;t!=root&&cnt[t]!=-1;t=fail[t])
{
ans+=cnt[t];
cnt[t]=-1;
}
}
return ans;
}
}ac;
char s[1000005];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
ac.init();
for(int i=1;i<=n;i++)
{
scanf("%s",s);
ac.add(s);
}
ac.build();
scanf("%s",s);
printf("%d\n",ac.match(s));
}
return 0;
}