AC自动机

下面的代码能过 洛谷P3808 【模板】AC自动机(简单版)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <queue>
 5 
 6 using namespace std;
 7 
 8 #define re register
 9 #define rep(i, x, y) for (register int i = x; i <= y; ++i)
10 #define repd(i, x, y) for (register int i = x; i >= y; --i)
11 
12 const int maxn = 1e6 + 5;
13 
14 int n, ans = 0;
15 char str[maxn];
16 
17 struct AC_automata {
18     #define SIGMA_SIZE 26
19     int f[maxn], ch[maxn][SIGMA_SIZE], val[maxn], sz, last[maxn];
20     inline int idx(char c) { return c - 'a'; }
21     void init() {
22         sz = 0;
23     }
24     void insert(char *t) {
25         int L = strlen(t), o = 0;
26         rep(i, 0, L - 1) {
27             if (ch[o][idx(t[i])]) o = ch[o][idx(t[i])];
28             else o = ch[o][idx(t[i])] = ++sz;
29         }
30         val[o]++;
31     }
32     void getfail() {
33         queue<int> q;
34         f[0] = 0;
35         rep(i, 0, SIGMA_SIZE - 1) {
36             re int u = ch[0][i];
37             if (u) { q.push(u); f[u] = 0; last[u] = 0; }
38         }
39         while (!q.empty()) {
40             re int r = q.front(); q.pop();
41             rep(i, 0, SIGMA_SIZE - 1) {
42                 re int u = ch[r][i];
43                 if (!u) { ch[r][i] = ch[f[r]][i]; continue; }
44                 q.push(u);
45                 re int v = f[r];
46                 while (v && !ch[v][i]) v = f[v];
47                 f[u] = ch[v][i];
48                 last[u] = val[f[u]] ? f[u] : last[f[u]];
49             }
50         }
51     }
52     void print(int o) {
53         if (o) {
54             ans += val[o];
55             val[o] = 0;
56             print(last[o]);
57         }
58     }
59     void find(char *T) {
60         re int L = strlen(T), o = 0;
61         rep(i, 0, L-1) {
62             re int c = idx(T[i]);
63             o = ch[o][c];
64             if (val[o]) print(o);
65             else if (last[o]) print(last[o]);
66         }
67     }
68 } ac;
69 
70 int main() {
71     scanf("%d", &n);
72 
73     ac.init();
74 
75     rep(i, 1, n) {
76         scanf("%s", str);
77         ac.insert(str);
78     }
79 
80     scanf("%s", str);
81 
82     ac.getfail();
83     ac.find(str);
84 
85     printf("%d", ans);
86     return 0;
87 }

 

posted @ 2018-10-29 22:33  AC-Evil  阅读(295)  评论(0编辑  收藏  举报