1 /************************************************************ 2 题目: Keywords Search(hdu 2222) 3 链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222 4 算法: ac自动机 5 算法思想: 多个字符串匹配,也就是相当于多个kmp 6 *************************************************************/ 7 #include<cstdio> 8 #include<cstring> 9 #include<algorithm> 10 #include<iostream> 11 #include<queue> 12 #include<vector> 13 using namespace std; 14 15 const int mx=1000000; 16 char str[mx]; 17 struct Node 18 { 19 int data; 20 int fail; 21 int count; 22 int next[26]; 23 void init(int a) 24 { 25 data=a; 26 fail=0; 27 count=0; 28 fill(next,next+26,-1); 29 } 30 }; 31 Node tree[mx]; 32 int cut; 33 34 void insert(char *s) 35 { 36 int p=0; 37 for (int i=0;s[i];i++) 38 { 39 int k=s[i]-'a'; 40 if (tree[p].next[k]==-1) 41 { 42 tree[cut].init(k); 43 tree[p].next[k]=cut++; 44 } 45 p=tree[p].next[k]; 46 } 47 tree[p].count++; 48 } 49 50 void ac() 51 { 52 int k=0; 53 queue<Node>q; 54 q.push(tree[0]); 55 while (!q.empty()) 56 { 57 Node u=q.front(); 58 q.pop(); 59 for (int i=0;i<26;i++) 60 { 61 if (u.next[i]!=-1) 62 { 63 if (u.data==-1) tree[u.next[i]].fail=0; 64 else 65 { 66 int v=u.fail; 67 while (v&&tree[v].next[i]==-1) v=tree[v].fail; 68 tree[u.next[i]].fail=max(tree[v].next[i],0); 69 } 70 q.push(tree[u.next[i]]); 71 } 72 } 73 } 74 } 75 76 int getans(char *s) 77 { 78 int k=0,ans=0; 79 for (int i=0;s[i];i++) 80 { 81 int x=s[i]-'a'; 82 while (k&&tree[k].next[x]==-1) k=tree[k].fail; 83 k=tree[k].next[x]; 84 if (k==-1) {k=0;continue;} 85 int j=k; 86 while (tree[j].count) 87 { 88 ans+=tree[j].count; 89 tree[j].count=0; 90 j=tree[j].fail; 91 } 92 ans+=tree[tree[j].fail].count; 93 tree[tree[j].fail].count=0; 94 } 95 return ans; 96 } 97 98 int main() 99 { 100 int t; 101 scanf("%d",&t); 102 while (t--) 103 { 104 cut=0; 105 tree[cut++].init(-1); 106 int n; 107 scanf("%d",&n); 108 while (n--) 109 { 110 scanf("%s",str); 111 insert(str); 112 } 113 ac(); 114 scanf("%s",str); 115 printf("%d\n",getans(str)); 116 } 117 }