AC自动机 模板

制作失配函数时注意两点:

一是从上往下计算,开个队列~

二是采用大白书的“一视同仁”法提高效率,就是一条边走不下去时直接把这条边接在失配函数的对应边上。

废话少说上代码~

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<algorithm>
  5 #include<cctype>
  6 //#include<iostream>
  7 using namespace std;
  8 
  9 #define maxt 1000011
 10 #define maxs 500011
 11 #define maxc 26
 12 int n;
 13 char s[maxs],T[maxt];int Case;
 14 struct Trie
 15 {
 16     int size,ch[maxs][maxc],fail[maxs],last[maxs],val[maxs],ans;bool vis[maxs];
 17     void clear() 
 18     {
 19         memset(ch[0],0,sizeof(ch[0]));
 20         memset(vis,0,sizeof(vis));
 21         val[0]=0;size=0;ans=0;
 22     }
 23     int idx(char c) {return c-'a';}
 24     void insert(char* s)
 25     {
 26         int now=0,ls=strlen(s);
 27         for (int i=0;i<ls;i++)
 28         {
 29             int id=idx(s[i]);
 30             if (!ch[now][id])
 31             {
 32                 ch[now][id]=++size;
 33                 memset(ch[size],0,sizeof(ch[size]));
 34                 val[size]=0;
 35             }
 36             now=ch[now][id];
 37         }
 38         val[now]++;
 39     }
 40     void make_fail()
 41     {
 42         int que[maxs],head,tail;
 43         head=tail=0;
 44         for (int i=0;i<maxc;i++)
 45         {
 46             int u=ch[0][i];
 47             if (u)
 48             {
 49                 fail[u]=0;
 50                 que[tail++]=u;
 51                 last[u]=0;
 52             }
 53         }
 54         while (head<tail)
 55         {
 56             int x=que[head++];
 57             for (int i=0;i<maxc;i++)
 58             {
 59                 int u=ch[x][i];
 60                 if (!u) {ch[x][i]=ch[fail[x]][i];continue;}
 61                 que[tail++]=u;
 62                 fail[u]=ch[fail[x]][i];
 63                 last[u]=val[fail[u]]?fail[u]:last[fail[u]];
 64             }
 65         }
 66     }
 67     void play(int x)
 68     {
 69         if (!x || vis[x]) return;
 70         ans+=val[x];
 71         vis[x]=1;
 72         play(last[x]);
 73     }
 74     void AC()
 75     {
 76         make_fail();
 77         int lt=strlen(T),now=0;
 78         for (int i=0;i<lt;i++)
 79         {
 80             int id=idx(T[i]);
 81             now=ch[now][id];
 82             if (val[now]) play(now);
 83             else if (last[now]) play(last[now]);
 84         }
 85         printf("%d\n",ans);
 86     }
 87 }trie;
 88 int main()
 89 {
 90     scanf("%d",&Case);
 91     while (Case--)
 92     {
 93         trie.clear();
 94         scanf("%d",&n);
 95         for (int i=1;i<=n;i++) scanf("%s",s),trie.insert(s);
 96         scanf("%s",T);
 97         trie.AC();
 98     }
 99     return 0;
100 }
View Code

 

posted @ 2017-09-03 22:17  Blue233333  阅读(137)  评论(0)    收藏  举报