$$AVICII$$

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 }
View Code

不解释,trie图比trie树好用

posted @ 2019-07-23 15:55  bootpuss  阅读(175)  评论(0编辑  收藏  举报