ac自动机模板by Lalatina (hdu 2222)
orzorz 日常%学弟 华科的未来orz
1#include <cstdio>
2#include <cstring>
3
4using namespace std;
5
6struct tnode {
7 int s;
8 tnode *f, *w, *c[26];
9} T[5000000], *Q[5000000];
10int C;
11
12inline tnode *tnew() {
13 memset(T + C, 0, sizeof(tnode));
14 return T + C++;
15}
16
17inline void AcaInsert(tnode *p, const char *s) {
18 while (*s) {
19 int u = *s - 'a';
20 if (!p->c[u])
21 p->c[u] = tnew();
22 p = p->c[u];
23 ++s;
24 }
25 ++p->s;
26}
27
28inline void AcaBuild(tnode *p) {
29 p->f = p->w = p;
30 int ql = 0;
31 for (int i = 0; i < 26; ++i)
32 if (p->c[i]) {
33 p->c[i]->f = p->c[i]->w = p;
34 Q[ql++] = p->c[i];
35 }
36 for (int qf = 0; qf < ql; ++qf)
37 for (int i = 0; i < 26; ++i)
38 if (Q[qf]->c[i]) {
39 tnode *f = Q[qf]->f;
40 while (f != p && !f->c[i])
41 f = f->f;
42 if (f->c[i]) {
43 Q[qf]->c[i]->f = f->c[i];
44 Q[qf]->c[i]->w = f->c[i]->s ? f->c[i] : f->c[i]->w;
45 }
46 else
47 Q[qf]->c[i]->f = Q[qf]->c[i]->w = p;
48 Q[ql++] = Q[qf]->c[i];
49 }
50}
51
52inline int AcaMatch(tnode *root, const char *s) {
53 int x = 0;
54 for (tnode *p = root; *s; ++s) {
55 while (p != root && !p->c[*s - 'a'])
56 p = p->f;
57 if (p->c[*s - 'a']) {
58 p = p->c[*s - 'a'];
59 for (tnode *q = p; q->s != -1; q = q->w) {
60 x += q->s;
61 q->s = -1;
62 }
63 }
64 }
65 return x;
66}
67
68char S[1000001];
69
70int main() {
71 int tt;
72 scanf("%d", &tt);
73 while (tt--) {
74 C = 0;
75 tnode *root = tnew();
76 root->s = -1;
77 int N;
78 scanf("%d", &N);
79 while (N--) {
80 scanf("%s", S);
81 AcaInsert(root, S);
82 }
83 AcaBuild(root);
84 scanf("%s", S);
85 printf("%d\n", AcaMatch(root, S));
86 }
87 return 0;
88}