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 }