最近正在学AC自动机,按照惯例需要刷一套kuangbin的AC自动机专题巩固

在网上看过很多模板,感觉kuangbin大神的模板最为简洁,于是就选择了用kuangbin大神的模板。

AC自动机其实就是字典树和KMP的结合,然后去思考一下KMP的原理,然后就是在字典树上实现KMP

这里最重要的思想可能就是fail的思想,就像KMP一样,匹配失败后,有一个next的数组去回溯(最长公共前缀后缀)

如何理解了KMP的话,感觉这个不会很难理解,字典树是一个非常简单的东西就不用讲了吧。

 

HDU - 2222,HDU - 2896,HDU - 3065,ZOJ - 3430

这是我总结出来的AC自动机解决的第一类问题,求文本串和模式串的关系(模式串出现几次之类的问题)

我把这几题放一起写了算了,因为套路一样随便改一下就好了

 

Keywords Search HDU - 2222

询问有多少个模式串出现在了文本串里面。

将模式串插入Trie树中,然后直接查询就好了。

  1 #include <set>
  2 #include <map>
  3 #include <stack>
  4 #include <queue>
  5 #include <cmath>
  6 #include <cstdio>
  7 #include <string>
  8 #include <vector>
  9 #include <time.h>
 10 #include <cstring>
 11 #include <iostream>
 12 #include <algorithm>
 13 #include <unordered_map>
 14 
 15 #define  pi acos(-1.0)
 16 #define  eps 1e-9
 17 #define  fi first
 18 #define  se second
 19 #define  rtl   rt<<1
 20 #define  rtr   rt<<1|1
 21 #define  bug               printf("******\n")
 22 #define  mem(a, b)         memset(a,b,sizeof(a))
 23 #define  name2str(x)       #x
 24 #define  fuck(x)           cout<<#x" = "<<x<<endl
 25 #define  sf(n)             scanf("%d", &n)
 26 #define  sff(a, b)         scanf("%d %d", &a, &b)
 27 #define  sfff(a, b, c)     scanf("%d %d %d", &a, &b, &c)
 28 #define  sffff(a, b, c, d) scanf("%d %d %d %d", &a, &b, &c, &d)
 29 #define  pf                printf
 30 #define  FIN               freopen("data.txt","r",stdin)
 31 #define  gcd(a, b)         __gcd(a,b)
 32 #define  lowbit(x)         x&-x
 33 #define  IO                iOS::sync_with_stdio(false)
 34 
 35 
 36 using namespace std;
 37 typedef long long LL;
 38 typedef unsigned long long ULL;
 39 const int maxn = 1e6 + 7;
 40 const int maxm = 8e6 + 10;
 41 const int INF = 0x3f3f3f3f;
 42 const int mod = 1e9 + 7;
 43 
 44 struct Aho_Corasick {
 45     int next[500010][26], fail[500010], End[500010];
 46     int root, cnt;
 47 
 48     int newnode() {
 49         for (int i = 0; i < 26; i++) next[cnt][i] = -1;
 50         End[cnt++] = 0;
 51         return cnt - 1;
 52     }
 53 
 54     void init() {
 55         cnt = 0;
 56         root = newnode();
 57     }
 58 
 59     void insert(char buf[]) {
 60         int len = strlen(buf);
 61         int now = root;
 62         for (int i = 0; i < len; i++) {
 63             if (next[now][buf[i] - 'a'] == -1) next[now][buf[i] - 'a'] = newnode();
 64             now = next[now][buf[i] - 'a'];
 65         }
 66         End[now]++;
 67     }
 68 
 69     void build() {
 70         queue<int> Q;
 71         fail[root] = root;
 72         for (int i = 0; i < 26; i++)
 73             if (next[root][i] == -1) next[root][i] = root;
 74             else {
 75                 fail[next[root][i]] = root;
 76                 Q.push(next[root][i]);
 77             }
 78         while (!Q.empty()) {
 79             int now = Q.front();
 80             Q.pop();
 81             for (int i = 0; i < 26; i++)
 82                 if (next[now][i] == -1) next[now][i] = next[fail[now]][i];
 83                 else {
 84                     fail[next[now][i]] = next[fail[now]][i];
 85                     Q.push(next[now][i]);
 86                 }
 87         }
 88     }
 89 
 90     int query(char buf[]) {
 91         int len = strlen(buf);
 92         int now = root;
 93         int res = 0;
 94         for (int i = 0; i < len; i++) {
 95             now = next[now][buf[i] - 'a'];
 96             int temp = now;
 97             while (temp != root) {
 98                 res += End[temp];
 99                 End[temp] = 0;
100                 temp = fail[temp];
101             }
102         }
103         return res;
104     }
105 
106     void debug() {
107         for (int i = 0; i < cnt; i++) {
108             printf("id = %3d,fail = %3d,end = %3d,chi = [", i, fail[i], End[i]);
109             for (int j = 0; j < 26; j++) printf("%2d", next[i][j]);
110             printf("]\n");
111         }
112     }
113 }ac;
114 
115 char buf[1000010];
116 int T,n;
117 int main() {
118     sf(T);
119     while(T--){
120         sf(n);
121         ac.init();
122         for (int i = 0; i < n; ++i) {
123             scanf("%s",buf);
124             ac.insert(buf);
125         }
126         scanf("%s",buf);
127         ac.build();
128         printf("%d\n",ac.query(buf));
129     }
130     return 0;
131 }
View Code

相关文章:

  • 2021-11-20
  • 2021-10-11
  • 2022-12-23
  • 2021-05-26
  • 2021-07-27
  • 2021-09-25
  • 2022-12-23
  • 2021-10-23
猜你喜欢
  • 2021-11-16
  • 2022-02-27
  • 2021-05-20
  • 2021-11-28
  • 2022-02-23
  • 2022-01-22
  • 2022-01-30
相关资源
相似解决方案