AC自动机 HDOJ 5384 Danganronpa
1 /*
2 题意:多个文本串,多个模式串在每个文本串出现的次数
3 AC自动机:这就是一道模板题,杭电有道类似的题目
4 */
5 /************************************************
6 * Author :Running_Time
7 * Created Time :2015-8-14 14:14:32
8 * File Name :AC.cpp
9 ************************************************/
10
11 #include <cstdio>
12 #include <algorithm>
13 #include <iostream>
14 #include <sstream>
15 #include <cstring>
16 #include <cmath>
17 #include <string>
18 #include <vector>
19 #include <queue>
20 #include <deque>
21 #include <stack>
22 #include <list>
23 #include <map>
24 #include <set>
25 #include <bitset>
26 #include <cstdlib>
27 #include <ctime>
28 using namespace std;
29
30 #define lson l, mid, rt << 1
31 #define rson mid + 1, r, rt << 1 | 1
32 typedef long long ll;
33 const int MAXN = 1e5 + 10;
34 const int MAXNODE = 6e5 + 10;
35 const int INF = 0x3f3f3f3f;
36 const int SIGMA_SIZE = 26;
37 const int MOD = 1e9 + 7;
38 ll res;
39 struct AC {
40 int ch[MAXNODE][SIGMA_SIZE], f[MAXNODE], sz;
41 ll val[MAXNODE];
42 void init(void) {
43 memset (ch[0], 0, sizeof (ch[0]));
44 sz = 1; val[0] = 0;
45 }
46 int idx(char c) {
47 return c - 'a';
48 }
49 void insert(string s) {
50 int u = 0; int len = s.size ();
51 for (int i=0; i<len; ++i) {
52 int c = idx (s[i]);
53 if (!ch[u][c]) {
54 memset (ch[sz], 0, sizeof (ch[sz]));
55 val[sz] = 0;
56 ch[u][c] = sz++;
57 }
58 u = ch[u][c];
59 }
60 val[u]++;
61 }
62 void build(void) {
63 queue<int> Q; f[0] = 0;
64 for (int i=0; i<SIGMA_SIZE; ++i) {
65 int u = ch[0][i];
66 if (u) {
67 f[u] = 0; Q.push (u);
68 }
69 }
70 while (!Q.empty ()) {
71 int r = Q.front (); Q.pop ();
72 for (int i=0; i<SIGMA_SIZE; ++i) {
73 int u = ch[r][i];
74 if (!u) {
75 ch[r][i] = ch[f[r]][i]; continue;
76 }
77 Q.push (u);
78 f[u] = ch[f[r]][i];
79 val[u] += val[f[u]];
80 }
81 }
82 }
83 ll query(string s) {
84 int len = s.size ();
85 ll ret = 0; int j = 0;
86 for (int i=0; i<len; ++i) {
87 int c = idx (s[i]);
88 j = ch[j][c];
89 ret += val[j];
90 }
91 return ret;
92 }
93 }ac;
94 string t[MAXN], p;
95
96 int main(void) { //HDOJ 5384 Danganronpa
97 int T; scanf ("%d", &T);
98 while (T--) {
99 int n, m; scanf ("%d%d", &n, &m);
100 ac.init ();
101 for (int i=1; i<=n; ++i) cin >> t[i];
102 for (int i=1; i<=m; ++i) {
103 cin >> p; ac.insert (p);
104 }
105 ac.build ();
106 for (int i=1; i<=n; ++i) {
107 printf ("%I64d\n", ac.query (t[i]));
108 }
109 }
110
111 return 0;
112 }
编译人生,运行世界!