Hdu 5384 Danganronpa (AC自动机模板)
题目链接:
题目描述:
给出n个目标串Ai,m个模式串Bj,问每个目标串中m个模式串出现的次数总和为多少?
解题思路:
与Hdu 2222 Keywords Search十分相似,hdu2222求目标串中包含几个模式串,本题目求模式串在目标串中出现了几次(比赛的时候模板都不会就悲剧了┭┮﹏┭┮)
初学AC自动机可以参考大神博客,总结的真的炒鸡棒讷。涨姿势请点击下面尊贵的链接大人:
学完AC自动机就可以套模板解决这个站在冰柜上的高冷题目了~~~~.
对所有的Bj建立Trie图,然后在Trie的基础上建立fail数组,在fail数组上每遇到一个Bj的终点,都会对计算结果有1的贡献。
1 #include <queue> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 8 const int maxn = 100005; 9 const int maxm = 10005; 10 char A[maxn][maxm], B[maxm]; 11 12 struct Trie 13 { 14 int next[maxn][26], fail[maxn], end[maxn]; 15 int L, root; 16 17 int newnode () 18 { 19 for (int i=0; i<26; i++) 20 next[L][i] = -1; 21 end[L] = 0; 22 return L++; 23 } 24 25 void init () 26 { 27 L = 0; 28 root = newnode(); 29 } 30 31 void insert (char s[]) 32 { 33 int now = root; 34 for (int i=0; s[i]; i++) 35 { 36 if (next[now][s[i]-'a'] == -1) 37 next[now][s[i]-'a'] = newnode(); 38 now = next[now][s[i]-'a']; 39 } 40 end[now] ++; 41 } 42 43 void build () 44 { 45 queue <int> Q; 46 fail[root] = root; 47 for (int i=0; i<26; i++) 48 if (next[root][i] == -1) 49 next[root][i] = root; 50 else 51 { 52 fail[next[root][i]] = root; 53 Q.push(next[root][i]); 54 } 55 while (!Q.empty()) 56 { 57 int now = Q.front(); 58 Q.pop (); 59 for (int i=0; i<26; i++) 60 { 61 if (next[now][i] == -1) 62 next[now][i] = next[fail[now]][i]; 63 else 64 { 65 fail[next[now][i]] = next[fail[now]][i]; 66 Q.push (next[now][i]); 67 } 68 } 69 } 70 } 71 72 int query (char s[]) 73 { 74 int now = root, res = 0; 75 for (int i=0; s[i]; i++) 76 { 77 now = next[now][s[i] - 'a']; 78 int temp = now; 79 while (temp != root) 80 { 81 res += end[temp]; 82 temp = fail[temp]; 83 } 84 } 85 return res; 86 } 87 }ac; 88 89 int main () 90 { 91 int t, n, m; 92 scanf ("%d", &t); 93 94 while (t --) 95 { 96 ac.init (); 97 scanf ("%d %d", &n, &m); 98 for (int i=0; i<n; i++) 99 scanf ("%s", A[i]); 100 101 for (int i=0; i<m; i++) 102 { 103 scanf ("%s", B); 104 ac.insert (B); 105 } 106 107 ac.build (); 108 for (int i=0; i<n; i++) 109 { 110 int res = ac.query(A[i]); 111 printf ("%d\n", res); 112 } 113 114 } 115 116 return 0; 117 }
本文为博主原创文章,未经博主允许不得转载。