[hdu3065]病毒侵袭持续中(AC自动机)

题意:给出多种病毒的号码和特征码,计算在某串中各病毒匹配的次数。

解题关键:AC自动机模板题,多组输入坑人。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=96;
 5 const int MAXN=50010;
 6 int num,ans[1002],nn;
 7 char vir[1002][52];
 8 struct Trie{//数组形式 
 9     int Next[MAXN][N],Fail[MAXN],End[MAXN],root,tot;//大小为所以匹配字符串的总和 
10     int newnode(){//结构体内部用 
11         for(int i=0;i<N;i++) Next[tot][i]=-1;
12         End[tot++]=0;
13         return tot-1;
14     }
15     void init(){
16         tot=0;
17         root=newnode();
18     }
19     void insert(char buf[],int x){
20         int len=strlen(buf);
21         int now=root;//now是temp指针 
22         for(int i=0;i<len;i++){
23             int k=buf[i]-32;
24             if(Next[now][k]==-1)  Next[now][k]=newnode();//next数组代表的是下一个字符索引 
25             now=Next[now][k];
26         }
27         End[now]=x;//end数组是当前字符串的个数.字典中可能有相同的单词,若只算一次,改为1. 
28     }
29     void build(){//构造fail指针,后缀是某些前缀 
30         queue<int>que;
31         Fail[root]=root;
32         for(int i=0;i<N;i++){ 
33             if(Next[root][i]==-1) Next[root][i]=root;
34             else{
35                 Fail[Next[root][i]]=root;
36                 que.push(Next[root][i]);
37             }
38         } 
39         while(!que.empty()){//bfs,会将所有的匹配子串都遍历到 
40             int now=que.front();
41             que.pop();
42             for(int i=0;i<N;i++){
43                 if(Next[now][i]==-1) Next[now][i]=Next[Fail[now]][i];
44                 else{
45                     Fail[Next[now][i]]=Next[Fail[now]][i];//fail指向最长的 
46                     que.push(Next[now][i]);
47                 }
48             }
49         }
50     }
51     void query(char buf[]){
52         int len=strlen(buf),now=root;
53         for(int i=0;i<len;i++){
54             now=Next[now][buf[i]-32];
55             int temp=now;
56             while(temp!=root){
57                 if(End[temp]) ans[End[temp]]++;
58                 temp=Fail[temp];
59             }
60         }
61     }
62 };
63 
64 Trie ac;
65 char buf[2000004];
66 int n,m;
67 int main(){
68     while(scanf("%d",&n)!=EOF){
69         memset(ans,0,sizeof ans);
70         ac.init();
71         for(int i=1;i<=n;i++){
72             scanf("%s",vir+i);
73             ac.insert(vir[i],i);
74         }
75            ac.build();//不要忘记build 
76            scanf("%s",buf);
77         ac.query(buf);
78         for(int i=1;i<=n;i++){
79             if(!ans[i]) continue;
80             printf("%s: %d\n",vir[i],ans[i]);
81         }
82     }
83 
84     return 0;
85 } 

 

posted @ 2017-09-11 21:52  Elpsywk  阅读(151)  评论(0编辑  收藏  举报