#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <string.h> #include <queue> //AC自动机模板题(动态建立) hdu2222 using namespace std; char a[1000005], b[55]; struct trie { trie *next[26]; trie *fail; //失败指针,类似于kmp中的next int g; trie() { for(int t=0; t<26; ++t) next[t]=NULL; fail=NULL; g=0; } }*root; void create(char *p) { int t=0, k, j=strlen(p); trie *q=root; while(t<j) { k=p[t]-'a'; if(!q->next[k]) { q->next[k]=new trie(); } q=q->next[k]; t++; } q->g++; //若重复也算,则加上去 return ; } void makefail() { queue<trie *> q; q.push(root); while(!q.empty()) { trie *p=q.front(), *temp; q.pop(); for(int t=0; t<26; ++t) { if(p->next[t]) { temp=p; if(p==root) { temp->next[t]->fail=p; } else { while(temp->fail) { if(temp->fail->next[t]) { p->next[t]->fail=temp->fail->next[t]; break; } temp=temp->fail; } if(!temp->fail) { p->next[t]->fail=root; } } q.push(p->next[t]); } } } return ; } int f(char *p) { int t, k, s=0, j=strlen(p); trie *q=root; for(t=0; t<j; ++t) { k=p[t]-'a'; while(q!=root&&q->next[k]==NULL) { q=q->fail; } q=q->next[k]; if(!q)q=root; trie *temp=q; while(temp!=root&&temp->g) { s+=temp->g; //加上重复的 temp->g=0; temp=temp->fail; } } return s; } int main() { int n, t, T; scanf("%d", &T); while(T--) { root=new trie(); scanf("%d", &n); for(t=0; t<n; ++t) { scanf("%s", b); create(b); } makefail(); scanf("%s", a); printf("%d\n", f(a)); } return 0; }
AC自动机模板 hdu2222
最新推荐文章于 2017-05-12 21:40:16 发布