hdu2222(ac自动机模板)
Posted ygeloutingyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu2222(ac自动机模板)相关的知识,希望对你有一定的参考价值。
先推荐两篇写的很好的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 }
以上是关于hdu2222(ac自动机模板)的主要内容,如果未能解决你的问题,请参考以下文章