queue<int> q; voidbuild(){ for (int i = 0; i < 26; i++) if (nd[0].son[i]) q.push(nd[0].son[i]); while (!q.empty()) { int u = q.front(); q.pop(); for (int i = 0; i < 26; i++) if (nd[u].son[i]) nd[nd[u].son[i]].fail = nd[nd[u].fail].son[i], q.push(nd[u].son[i]); else nd[u].son[i] = nd[nd[u].fail].son[i]; } }
匹配
遍历文本串 T,设当前点为 u:
利用 fail 找到所有匹配的模式串,累加,清零。
1 2 3 4 5 6 7 8 9 10
intquery(char *t){ int u = 0, sum = 0; for (int i = 1; t[i]; i++) { int c = t[i] - 'a'; u = nd[u].son[c]; for (int j = u; j && nd[j].e != -1; j = nd[j].fail) sum += nd[j].e, nd[j].e = -1; } return sum; }
#include<queue> #include<stdio.h> usingnamespace std; constint N = 1e6 + 5; int n; structAC { int cnt; structnode { int son[30], fail, e; } nd[N]; voidinsert(char *s){ int u = 0; for (int i = 1; s[i]; i++) { int c = s[i] - 'a'; if (!nd[u].son[c]) nd[u].son[c] = ++cnt; u = nd[u].son[c]; } nd[u].e++; } queue<int> q; voidbuild(){ for (int i = 0; i < 26; i++) if (nd[0].son[i]) q.push(nd[0].son[i]); while (!q.empty()) { int u = q.front(); q.pop(); for (int i = 0; i < 26; i++) if (nd[u].son[i]) nd[nd[u].son[i]].fail = nd[nd[u].fail].son[i], q.push(nd[u].son[i]); else nd[u].son[i] = nd[nd[u].fail].son[i]; } } intquery(char *t){ int u = 0, sum = 0; for (int i = 1; t[i]; i++) { int c = t[i] - 'a'; u = nd[u].son[c]; for (int j = u; j && nd[j].e != -1; j = nd[j].fail) sum += nd[j].e, nd[j].e = -1; } return sum; } } ac; char s[N]; intmain(){ scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%s", s + 1), ac.insert(s); ac.build(); scanf("%s", s + 1); printf("%d\n", ac.query(s)); return0; }
#include<cstring> #include<queue> #include<stdio.h> usingnamespace std; constint N = 156, T = 1e6 + 6, S = N * 80; structAC { int cnt, ans[N]; structnode { int son[30], fail, idx, val; } nd[S]; voidinit(){ memset(nd, 0, sizeof nd); memset(ans, 0, sizeof(ans)); cnt = 0; } voidinsert(char *s, int id){ int u = 0; for (int i = 1; s[i]; i++) { int c = s[i] - 'a'; if (!nd[u].son[c]) nd[u].son[c] = ++cnt; u = nd[u].son[c]; } nd[u].idx = id; } queue<int> q; voidbuild(){ for (int i = 0; i < 26; i++) if (nd[0].son[i]) q.push(nd[0].son[i]); while (q.size()) { int u = q.front(); q.pop(); for (int i = 0; i < 26; i++) if (nd[u].son[i]) nd[nd[u].son[i]].fail = nd[nd[u].fail].son[i], q.push(nd[u].son[i]); else nd[u].son[i] = nd[nd[u].fail].son[i]; } } intquery(char *t){ int u = 0, sum = 0; for (int i = 1; t[i]; i++) { int c = t[i] - 'a'; u = nd[u].son[c]; for (int j = u; j; j = nd[j].fail) nd[j].val++; } for (int i = 0; i <= cnt; i++) if (nd[i].idx) sum = max(sum, nd[i].val), ans[nd[i].idx] = nd[i].val; return sum; } } ac; int n; char s[N][100], t[T]; intmain(){ while (scanf("%d", &n)) { if (n == 0) break; for (int i = 1; i <= n; i++) scanf("%s", s[i] + 1), ac.insert(s[i], i); ac.build(); scanf("%s", t + 1); int x = ac.query(t); printf("%d\n", x); for (int i = 1; i <= n; i++) if (ac.ans[i] == x) printf("%s\n", s[i] + 1); ac.init(); } return0; }
#include<queue> #include<stdio.h> usingnamespace std; constint N = 2e5 + 5, S = 2e5 + 5, T = 2e6 + 5; char s[S], t[T]; int n; structAC { int cnt = 1, ans[N], f[N], in[N]; structnode { int son[27], fail, f, ans; } nd[N];
queue<int> q;
voidinsert(char *s, int id){ int u = 1; for (int i = 1; s[i]; i++) { int c = s[i] - 'a'; if (!nd[u].son[c]) nd[u].son[c] = ++cnt; u = nd[u].son[c]; } f[id] = (nd[u].f) ? nd[u].f : nd[u].f = id; return; }
voidbuild(){ for (int i = 0; i < 26; i++) nd[0].son[i] = 1; nd[1].fail = 0; q.push(1); while (!q.empty()) { int u = q.front(); q.pop(); int fail = nd[u].fail; for (int i = 0; i < 26; i++) { int v = nd[u].son[i]; if (!v) { nd[u].son[i] = nd[fail].son[i]; continue; } nd[v].fail = nd[fail].son[i], in[nd[fail].son[i]]++; q.push(v); } } }
voidtopsort(){ for (int i = 1; i <= cnt; i++) if (!in[i]) q.push(i); while (!q.empty()) { int u = q.front(); q.pop(); ans[nd[u].f] = nd[u].ans; int fail = nd[u].fail; nd[fail].ans += nd[u].ans; if (!--in[fail]) q.push(fail); } }
voidquery(char *s){ int u = 1; for (int i = 1; s[i]; i++) u = nd[u].son[s[i] - 'a'], nd[u].ans++; } } ac;
intmain(){ scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%s", s + 1), ac.insert(s, i); ac.build(); scanf("%s", t + 1); ac.query(t), ac.topsort(); for (int i = 1; i <= n; i++) printf("%d\n", ac.ans[ac.f[i]]); return0; }
#include<deque> #include<stdio.h> usingnamespace std; typedef deque<int> dq; constint N = 2e5 + 5, S = 2e5 + 5, T = 2e6 + 5; int n; char s[S], t[T]; int cnt[N]; structACM { structnode { int son[30], val, fail, hd; dq idx; } nd[S]; structedge { int to, nt; } e[S]; int rt, acnt, tot; voidinsert(char *s, int id){ int u = rt; for (int i = 1; s[i]; i++) { int c = s[i] - 'a' + 1; if (!nd[u].son[c]) nd[u].son[c] = ++acnt; u = nd[u].son[c]; } nd[u].idx.push_back(id); } voidbuild(){ dq q; for (int i = 1; i <= 26; i++) if (nd[rt].son[i]) q.push_back(nd[rt].son[i]); while (!q.empty()) { int u = q.front(); q.pop_front(); for (int i = 1; i <= 26; i++) if (nd[u].son[i]) { nd[nd[u].son[i]].fail = nd[nd[u].fail].son[i]; q.push_back(nd[u].son[i]); } else nd[u].son[i] = nd[nd[u].fail].son[i]; } }
voidquery(char *s){ int u = rt; for (int i = 1; s[i]; i++) { int c = s[i] - 'a' + 1; u = nd[u].son[c], nd[u].val++; } }
voidadd(int u, int v){ e[++tot] = {v, nd[u].hd}, nd[u].hd = tot; }
voiddfs(int x){ for (int i = nd[x].hd; i; i = e[i].nt) { int v = e[i].to; dfs(v); nd[x].val += nd[v].val; } for (auto i : nd[x].idx) cnt[i] += nd[x].val; }
voidfailtr(){ for (int u = 1; u <= acnt; u++) add(nd[u].fail, u); dfs(rt); } } ac;
intmain(){ scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%s", s + 1); ac.insert(s, i); } ac.build(); scanf("%s", t + 1); ac.query(t), ac.failtr(); for (int i = 1; i <= n; i++) printf("%d\n", cnt[i]); return0; }