题目: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 ",ac.match(s)); } return 0; }