参考:http://www.cppblog.com/mythit/archive/2009/04/21/80633.html
1 /*
2 * AC自动机
3 */
4 #include <cstdio>
5 #include <cstdlib>
6 #include <cstring>
7 #include <iostream>
8
9 using namespace std;
10
11 const int N = 51;
12 const int L = 500001;
13 const int M = 1000001;
14
15 char pat[N], str[M];
16 struct node {//节点数据
17 int c;
18 node *prefix;
19 node *child[26];
20 node() {
21 c = 0;
22 prefix = NULL;
23 for (int i=0; i<26; ++i) child[i] = NULL;
24 }
25 }*root, *Q[L];
26 int front, rear;
27
28 void insert(node *root, char pat[]) {//建立字典树
29 node *p = root;
30 for (int k,i=0; pat[i]; ++i, p=p->child[k]) {
31 k = pat[i] - 'a';
32 if (!p->child[k]) p->child[k] = new node();
33 }
34 ++p->c;
35 }
36
37 void buildAc(node *root) {//建立自动机
38 node *p, *q;
39 root->prefix = NULL;
40 front = rear = 0;
41 Q[front++] = root;
42 while (rear < front) {
43 p = Q[rear++];
44 for (int i=0; i<26; ++i) {
45 if (p->child[i]) {
46 if (p == root) p->child[i]->prefix = root;
47 else {
48 q = p->prefix;
49 while (q!=root && !q->child[i]) q = q->prefix;
50 if (q->child[i]) p->child[i]->prefix = q->child[i];
51 else p->child[i]->prefix = root;
52 }
53 Q[front++] = p->child[i];
54 }
55 }
56 }
57 }
58
59 int match(node *root, char str[]) {//匹配
60 node *p = root;
61 int cnt = 0;
62 for (int k,i=0; str[i]; ++i) {
63 k = str[i] - 'a';
64 while (!p->child[k] && p!=root) p = p->prefix;
65 p = p->child[k];
66 if (p==NULL) p = root;
67 node *tmp = p;
68 while (tmp!=root && tmp->c) {
69 cnt += tmp->c;
70 tmp->c = 0;
71 tmp = tmp->prefix;
72 }
73 }
74 return cnt;
75 }
76
77 int main() {
78 int t;
79 scanf ("%d", &t);
80 while (t--) {
81 int n;
82 scanf ("%d", &n);
83 root = new node();
84 while (n--) scanf ("%s", pat), insert(root, pat);
85 scanf ("%s", str);
86 buildAc(root);
87 printf ("%d\n", match(root, str));
88 }
89 return 0;
90 }