码迷,mamicode.com
首页 > 其他好文 > 详细

hdu2222(ac自动机模板)

时间:2017-08-23 21:41:26      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:nod   模式   debug   build   strlen   void   detail   push   lan   

先推荐两篇写的很好的ac自动机blog:

http://blog.csdn.net/creatorx/article/details/71100840

http://blog.csdn.net/niushuai666/article/details/7002823

 

正题

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222

 

题意: 给出 n 个模式串以及一个 主串, 问有多少个模式串在主串中出现过

 

思路: ac自动机模板题

 

代码:

技术分享
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <queue>
 5 using namespace std;
 6 
 7 const int MAXN = 5e5 + 10;
 8 
 9 struct Trie{
10     int next[MAXN][26], fail[MAXN], end[MAXN];
11     int root, L;
12     int newnode(){//初始化字典树节点
13         for(int i = 0; i < 26; i++){
14             next[L][i] = -1;
15         }
16         end[L++] = 0;
17         return L - 1;
18     }
19     void init(){//初始化字典树根节点
20         L = 0;
21         root = newnode();
22     }
23     void insert(char buf[]){//往字典树中插入一个单词
24         int len = strlen(buf);
25         int now = root;
26         for(int i = 0; i < len; i++){
27             if(next[now][buf[i] - a] == -1) next[now][buf[i] - a] = newnode();
28             now = next[now][buf[i] - a];
29         }
30         end[now]++;
31     }
32     void build(){ //构造fail数组
33         queue<int> Q;
34         fail[root] = root;
35         for(int i = 0; i < 26; i++){
36             if(next[root][i] == -1) next[root][i] = root;
37             else{
38                 fail[next[root][i]] = root;
39                 Q.push(next[root][i]);
40             }
41         }
42         while(!Q.empty()){
43             int now = Q.front();
44             Q.pop();
45             for(int i = 0; i < 26; i++)
46             if(next[now][i] == -1) next[now][i] = next[fail[now]][i];
47             else{
48                 fail[next[now][i]] = next[fail[now]][i];
49                 Q.push(next[now][i]);
50             }
51         }
52     }
53     int query(char buf[]){
54         int len = strlen(buf);
55         int now = root;
56         int res = 0;
57         for(int i = 0; i < len; i++){
58             now = next[now][buf[i] - a];
59             int temp = now;
60             while(temp != root){
61                 res += end[temp];
62                 end[temp] = 0; // 每个模式串只算一次,所以清0
63                 temp = fail[temp];
64             }
65         }
66         return res;
67     }
68     void debug(){
69         for(int i = 0; i < L; i++){
70             printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]);
71             for(int j = 0; j < 26; j++){
72                 printf("%2d",next[i][j]);
73             }
74             printf("]\n");
75         }
76     }
77 };
78 
79 Trie ac;
80 char buf[MAXN << 1];
81 
82 int main(void){
83     int t, n;
84     scanf("%d", &t);
85     while(t--){
86         ac.init();
87         scanf("%d", &n);
88         for(int i = 0; i < n; i++){
89             scanf("%s", buf);
90             ac.insert(buf);
91         }
92         ac.build();
93         scanf("%s", buf);
94         printf("%d\n", ac.query(buf));
95     }
96     return 0;
97 }
View Code

 

hdu2222(ac自动机模板)

标签:nod   模式   debug   build   strlen   void   detail   push   lan   

原文地址:http://www.cnblogs.com/geloutingyu/p/7420175.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!