HDU 3065 病毒侵袭持续中 (AC自动机)

题意:找出模式串出现的种类是什么以及它们的次数

思路:拿一个数组存end的出现次数。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<string>
 6 #include<algorithm>
 7 #include<queue>
 8 #define maxn 50005
 9 char s[2000005],a[1005][105];
10 int n,num[1005];
11 struct Trie{
12     int fail[maxn],end[maxn],next[maxn][130],L,root;
13     int newnode(){
14         for (int i=0;i<128;i++)
15          next[L][i]=-1;
16         end[L++]=-1;
17         return L-1; 
18     }
19     void clear(){
20         L=0;
21         root=newnode();
22     }
23     void insert(char s[],int id){
24         int now=root,len=strlen(s);
25         for (int i=0;i<len;i++){
26             if (next[now][s[i]]==-1) next[now][s[i]]=newnode();
27             now=next[now][s[i]];
28         }
29         end[now]=id;
30     }
31     void build(){
32         std::queue<int>Q;
33         int now=root;
34         for (int i=0;i<128;i++)
35          if (next[root][i]==-1) next[root][i]=root;
36         else{
37             fail[next[root][i]]=root;
38             Q.push(next[root][i]);
39         } 
40         while (!Q.empty()){
41             now=Q.front();Q.pop();
42             for (int i=0;i<128;i++){
43                 if (next[now][i]==-1)
44                  next[now][i]=next[fail[now]][i];
45                 else{
46                     fail[next[now][i]]=next[fail[now]][i];
47                     Q.push(next[now][i]);
48                 } 
49             }
50         }
51     }
52     void query(char s[]){
53         int len=strlen(s),now=root;
54         for (int i=0;i<=n;i++)
55          num[i]=0;
56         for (int i=0;i<len;i++){
57             now=next[now][s[i]];
58             int tmp=now;
59             while (tmp!=root){
60                 if (end[tmp]!=-1)
61                 num[end[tmp]]++;
62                 tmp=fail[tmp];
63             }
64         }
65         for (int i=1;i<=n;i++)
66          if (num[i]){
67              int len=strlen(a[i]);
68              for (int j=0;j<len;j++)
69               printf("%c",a[i][j]);
70              printf(": %d",num[i]);
71             printf("\n");  
72          }
73     }
74 }ac;
75 int main(){
76     while (scanf("%d",&n)!=EOF){
77         ac.clear();
78         for (int i=1;i<=n;i++){
79             scanf("%s",a[i]);
80             ac.insert(a[i],i);
81         }
82         ac.build();
83         scanf("%s",s);
84         ac.query(s);
85     }
86 }

 

posted @ 2016-06-02 08:11  GFY  阅读(177)  评论(0编辑  收藏  举报