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 }

 

posted on 2016-07-16 10:26  pb2016  阅读(310)  评论(0编辑  收藏  举报