AC trie图
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<queue>
5 using namespace std;
6 int T,n;
7 char ci[51],zhu[1000001];
8 struct actrie{
9 int count;
10 actrie *tr[26],*fail;
11 };
12 actrie *root;
13 actrie *new_trie(){
14 actrie *tmp=new actrie;
15 tmp->count=0;
16 for(int i=0;i<26;++i)tmp->tr[i]=NULL;
17 tmp->fail=NULL;
18 return tmp;
19 }
20 void insert(char c[]){
21 int len=strlen(c+1);
22 actrie *tmp=root;
23 for(int i=1;i<=len;++i){
24 int index=c[i]-'a';
25 if(tmp->tr[index]==NULL)tmp->tr[index]=new_trie();
26 tmp=tmp->tr[index];
27 }
28 tmp->count++;
29 }
30 int cc;
31 queue<actrie *>dd;
32 void get_fail(){
33 actrie *tmp=root;
34 tmp->fail=NULL;//the fail of root
35 for(int i=0;i<26;++i)
36 if(tmp->tr[i]!=NULL){
37 tmp->tr[i]->fail=root;
38 dd.push(tmp->tr[i]);
39 }
40 while(!dd.empty()){
41 tmp=dd.front();dd.pop();
42 for(int i=0;i<26;++i)
43 if(tmp->tr[i]!=NULL)
44 {
45 actrie *p=tmp->fail;
46 while(p!=NULL){
47 if(p->tr[i]!=NULL){
48 tmp->tr[i]->fail=p->tr[i];
49 // cout<<++cc<<endl;
50 break;
51 }
52 p=p->fail;
53 }
54 if(p==NULL){
55 tmp->tr[i]->fail=root;
56 // cout<<++cc<<endl;
57 }
58 dd.push(tmp->tr[i]);
59 }
60 else if(tmp!=root)tmp->tr[i]=tmp->fail->tr[i];
61 else tmp->tr[i]=root;
62 }
63 }
64 int AC_query(char c[]){
65 int len=strlen(c+1);
66 int res=0;
67 actrie *tmp=root;
68 for(int i=1;i<=len;++i){
69 int index=c[i]-'a';
70 // while(tmp!=root&&tmp->tr[index]==NULL)tmp=tmp->fail;
71 tmp=tmp->tr[index];
72 if(tmp==NULL)tmp=root;
73 actrie *lin=tmp;
74 while(lin!=root){
75 if(lin->count==-1)break;
76 res+=lin->count;
77 lin->count=-1;
78 lin=lin->fail;
79 }
80 }
81 return res;
82 }
83 int main(){
84 scanf("%d",&T);
85 while(T){
86 --T;
87 scanf("%d",&n);
88 root=new_trie();
89 for(int i=1;i<=n;++i){
90 scanf("%s",ci+1);
91 insert(ci);
92 }
93 get_fail();
94 scanf("%s",zhu+1);
95 printf("%d\n",AC_query(zhu));
96 }
97 }
不解释,trie图比trie树好用