hdu2222 Keywords Search ac自动机模板题

题目链接:Keywords Search

题意:给你n个字符串不长度超过50,然后在给一个串ss问有多少个串在这个ss串里面出现过,

题解:ac自动机的入门模板题,学习资料,要求先会kmp,和字典树。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=1e4*50+100;
  4 const int N=1e4*50+100;
  5 char op[55],ss[(int)1e6+10];
  6 struct ac_auto
  7 {
  8     int nxt[N][26],ed[N],fail[N],cn,rt;
  9     ac_auto(){}
 10     void init(){
 11         memset(nxt,-1,sizeof(nxt));
 12         memset(ed,0,sizeof(ed));
 13         memset(fail,-1,sizeof(fail));
 14         cn=0;
 15         rt=new_node();
 16     }
 17     int new_node()
 18     {
 19         return cn++;
 20     }
 21     void insert(char *s)
 22     {
 23         int len=strlen(s);
 24         int p=rt;
 25         for(int i=0;i<len;i++)
 26         {
 27             int x=s[i]-'a';
 28             if(nxt[p][x]==-1)nxt[p][x]=new_node();
 29             p=nxt[p][x];
 30         }
 31         ed[p]++;
 32     }
 33     void get_fail()
 34     {
 35         queue<int>que;
 36         que.push(rt);
 37         while(!que.empty())
 38         {
 39             int s=que.front();que.pop();
 40             for(int i=0;i<26;i++)
 41             {
 42                 if(nxt[s][i]!=-1)
 43                 {
 44                     if(s==rt)
 45                     {
 46                         fail[nxt[s][i]]=rt;
 47                     }
 48                      else
 49                     {
 50                         int p=fail[s];
 51                         while(p!=-1)
 52                         {
 53                             if(nxt[p][i]!=-1)
 54                             {
 55                                 fail[nxt[s][i]]=nxt[p][i];break;
 56                             }
 57                             p=fail[p];
 58                         }
 59                         if(p==-1)fail[nxt[s][i]]=rt;
 60                     }
 61                     que.push(nxt[s][i]);
 62                 }
 63 
 64             }
 65         }
 66     }
 67     int ac_automation(char *s)
 68     {
 69         int p=rt;int ans=0;
 70         int len=strlen(s);
 71         for(int i=0;i<len;i++)
 72         {
 73             int x=s[i]-'a';
 74             while(p!=-1&&nxt[p][x]==-1)p=fail[p];
 75             if(p==-1)p=rt;
 76             else p=nxt[p][x];
 77             int tmp=p;
 78             while(tmp!=rt)
 79             {
 80                 if(ed[tmp]>0)ans+=ed[tmp],ed[tmp]=0;
 81                 else break;
 82                 tmp=fail[tmp];
 83             }
 84         }
 85         return ans;
 86     }
 87 }ac;
 88 int main()
 89 {
 90     int T;
 91     scanf("%d",&T);
 92     while(T--)
 93     {
 94         ac.init();
 95         int n;
 96         scanf("%d",&n);
 97         for(int i=0;i<n;i++)scanf("%s",op),ac.insert(op);
 98         ac.get_fail();
 99         scanf("%s",ss);
100         printf("%d\n",ac.ac_automation(ss));
101     }
102 }

 

posted @ 2018-08-05 14:37  lhclqslove  阅读(163)  评论(0编辑  收藏  举报