AC自动机

Posted 秦时、长浩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AC自动机相关的知识,希望对你有一定的参考价值。

解决字符串问题

技术分享
  1 #include <stdio.h>
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <string.h>
  5 #include <queue>
  6 using namespace std;
  7 
  8 struct Trie
  9 {
 10     int next[500010][26],fail[500010],end[500010];
 11     int root,L;
 12     int newnode()
 13     {
 14         for(int i = 0;i < 26;i++)
 15             next[L][i] = -1;
 16         end[L++] = 0;
 17         return L-1;
 18     }
 19     void init()
 20     {
 21         L = 0;
 22         root = newnode();
 23     }
 24     void insert(char buf[])
 25     {
 26         int len = strlen(buf);
 27         int now = root;
 28         for(int i = 0;i < len;i++)
 29         {
 30             if(next[now][buf[i]-a] == -1)
 31                 next[now][buf[i]-a] = newnode();
 32             now = next[now][buf[i]-a];
 33         }
 34         end[now]++;
 35     }
 36     void build()
 37     {
 38         queue<int>Q;
 39         fail[root] = root;
 40         for(int i = 0;i < 26;i++)
 41             if(next[root][i] == -1)
 42                 next[root][i] = root;
 43             else
 44             {
 45                 fail[next[root][i]] = root;
 46                 Q.push(next[root][i]);
 47             }
 48         while( !Q.empty() )
 49         {
 50             int now = Q.front();
 51             Q.pop();
 52             for(int i = 0;i < 26;i++)
 53                 if(next[now][i] == -1)
 54                     next[now][i] = next[fail[now]][i];
 55                 else
 56                 {
 57                     fail[next[now][i]]=next[fail[now]][i];
 58                     Q.push(next[now][i]);
 59                 }
 60         }
 61     }
 62     int query(char buf[])
 63     {
 64         int len = strlen(buf);
 65         int now = root;
 66         int res = 0;
 67         for(int i = 0;i < len;i++)
 68         {
 69             now = next[now][buf[i]-a];
 70             int temp = now;
 71             while( temp != root )
 72             {
 73                 res += end[temp];
 74                 end[temp] = 0;
 75                 temp = fail[temp];
 76             }
 77         }
 78         return res;
 79     }
 80     void debug()
 81     {
 82         for(int i = 0;i < L;i++)
 83         {
 84             printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]);
 85             for(int j = 0;j < 26;j++)
 86                 printf("%2d",next[i][j]);
 87             printf("]\n");
 88         }
 89     }
 90 };
 91 char buf[1000010];
 92 Trie ac;
 93 int main()
 94 {
 95     int T;
 96     int n;
 97     scanf("%d",&T);
 98     while( T-- )
 99     {
100         scanf("%d",&n);
101         ac.init();
102         for(int i = 0;i < n;i++)
103         {
104             scanf("%s",buf);
105             ac.insert(buf);
106         }
107         ac.build();
108         scanf("%s",buf);
109         printf("%d\n",ac.query(buf));
110     }
111     return 0;
112 }
AC自动机

完事

以上是关于AC自动机的主要内容,如果未能解决你的问题,请参考以下文章

POJ3691DNA repair(AC自动机,DP)

HDU4057 Rescue the Rabbit(AC自动机+状压DP)

Codeforces 86C Genetic engineering(AC自动机+DP)

POJ1699 Best Sequence(AC自动机+状压DP)

POJ - 2778 ~ HDU - 2243 AC自动机+矩阵快速幂

HDU2457 DNA repair(AC自动机+DP)