HDU 2222 - Keywords Search
试个模板- -
/* HDU 2222 - Keywords Search [ AC自动机 ] */ #include <bits/stdc++.h> using namespace std; const int N = 500005; const int SIZE = 26; struct Trie { int ch[N][SIZE]; int f[N], last[N], cnt[N], val[N]; int tot, ans; void init() { tot = 0; memset(ch, 0, sizeof(ch)); memset(val, 0, sizeof(val)); } int ord(char c) { return c-'a'; } void insert(char* s) { int now = 0, n = strlen(s); for (int i = 0; i < n; i++) { int t = ord(s[i]); if (!ch[now][t]) ch[now][t] = ++tot; now = ch[now][t]; } val[now]++; } void getFail() { queue<int> Q; f[0] = 0; for (int t = 0; t < SIZE; t++) { int now = ch[0][t]; if (now) { f[now] = last[now] = 0; Q.push(now); } } while (!Q.empty()) { int k = Q.front(); Q.pop(); for (int t = 0; t < SIZE; t++) { int now = ch[k][t]; if(!now) continue; Q.push(now); int nxt = f[k]; while (nxt && !ch[nxt][t]) nxt=f[nxt]; f[now] = ch[nxt][t]; last[now] = val[f[now]] ? f[now] : last[f[now]]; } } } void add(int now) { for (; now; now = last[now]) ans += val[now], val[now] = 0; } void Find(char* s) { int now = 0, n = strlen(s); ans = 0; for (int i = 0; i < n; i++) { int t = ord(s[i]); while (now && !ch[now][t]) now = f[now]; now = ch[now][t]; if (val[now]) add(now); else if (last[now]) add(last[now]); } } }ac; char s[1000005]; int main() { int t; scanf("%d", &t); while (t--) { ac.init(); int n; scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%s", s); ac.insert(s); } ac.getFail(); scanf("%s", s); ac.Find(s); printf("%d\n", ac.ans); } }
#include <bits/stdc++.h> using namespace std; const int N = 500005; struct Tire { int ch[N][26], f[N], tot; int val[N], vis[N]; void init() { tot = 0; memset(ch, 0, sizeof(ch)); memset(f, 0, sizeof(f)); memset(val, 0, sizeof(val)); } int ord(char c) { return c - 'a'; } void insert(char* s) { int now = 0, n = strlen(s); for (int i = 0; i < n; i++) { int t = ord(s[i]); if (!ch[now][t]) ch[now][t] = ++tot; now = ch[now][t]; } val[now]++; } void buildFail() { queue<int> Q; f[0] = 0; for (int t = 0; t < 26; t++) { int now = ch[0][t]; if (now) { Q.push(now); f[now] = 0; } } while (!Q.empty()) { int now = Q.front(); Q.pop(); for (int t = 0; t < 26; t++) { int v = ch[now][t]; if (!v) {ch[now][t] = ch[f[now]][t]; continue; } Q.push(v); int nxt = f[now]; while (nxt && !ch[nxt][t]) nxt = f[nxt]; f[v] = ch[nxt][t]; } } } int Find(char *s) { int ans = 0; int n = strlen(s), now = 0; memset(vis, 0, sizeof(vis)); for (int i = 0; i < n; i++) { int t = ord(s[i]); // while (now && !ch[now][t]) now = f[now]; now = ch[now][t]; int tmp = now; while (tmp) { if (vis[tmp]) break; vis[tmp] = 1; ans += val[tmp]; val[tmp] = 0; tmp = f[tmp]; } } return ans; } }ac; char s[1000005]; int t, n; int main() { scanf("%d", &t); while (t--) { scanf("%d", &n); ac.init(); while (n--) { scanf("%s", s); ac.insert(s); } ac.buildFail(); scanf("%s", s); printf("%d\n", ac.Find(s)); } }
我自倾杯,君且随意