AC自动机
Posted jionkitten
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AC自动机相关的知识,希望对你有一定的参考价值。
题源:https://www.luogu.com.cn/problem/P3796
debug了一下午发现代码又抄错了,数组大小也开错了,数据范围搞混了。。
#include <iostream> #include <stdio.h> #include <cstring> #include <queue> //#define LOCAL //#define fre #define maxn 1000005 using namespace std; char s[maxn], p[155][75]; int n; int nex[10510][26], fail[10510], e[10510], last[10510], ans[155]; //一开始这里开成了75.。。 struct Tire { int cnt; void init() { cnt = 1; memset(nex, 0xff, sizeof(nex)); memset(e, 0, sizeof(e)); memset(last, 0, sizeof(last)); } void insert(char s[], int t) { int len = strlen(s); int now = 0; for (int i = 0; i < len; ++i) { if (nex[now][s[i] - ‘a‘] == -1) nex[now][s[i] - ‘a‘] = cnt++; now = nex[now][s[i] - ‘a‘]; } e[now] = t; } void build() { queue<int> q; fail[0] = 0; last[0] = 0; for (int i = 0; i < 26; ++i) { if (nex[0][i] == -1) nex[0][i] = 0; else { fail[nex[0][i]] = 0; q.push(nex[0][i]); } } while (!q.empty()) { int now = q.front(); q.pop(); for (int i = 0; i < 26; ++i) { if (nex[now][i] == -1) { nex[now][i] = nex[fail[now]][i]; } else { fail[nex[now][i]] = nex[fail[now]][i]; last[nex[now][i]] = e[fail[nex[now][i]]] ? fail[nex[now][i]] : last[fail[nex[now][i]]];//last优化,就是这里抄错了555 q.push(nex[now][i]); } } } } int query(char p[], int n) { int len = strlen(p); int now = 0, res = 0; for (int i = 0; i < len; ++i) { now = nex[now][p[i] - ‘a‘]; for (int j = now; j; j = last[j]) { ans[e[j]]++; #ifdef LOCAL if (i == 2) cout << j << " " << e[j] << endl; if (e[j] == 5) cout << i << endl; #endif } } for (int i = 1; i <= n; ++i) { #ifdef LOCAL cout << i << " : " << ans[i] << endl; #endif res = max(res, ans[i]); } return res; } }; int main() { #ifdef fre freopen("in.in", "r", stdin); freopen("out.txt", "w", stdout); #endif Tire tr; while (scanf("%d", &n) && n) { tr.init(); memset(ans, 0, sizeof(ans)); for (int i = 1; i <= n; ++i) //注意从1开始,0已经被不断跳转回根节点占用了 { scanf("%s", p[i]); tr.insert(p[i], i); } tr.build(); scanf("%s", s); int tmp = tr.query(s, n); printf("%d ", tmp); if (tmp == 0) continue; for (int i = 1; i <= n; ++i) { if (ans[i] == tmp) printf("%s ", p[i]); } } }
以上是关于AC自动机的主要内容,如果未能解决你的问题,请参考以下文章
HDU4057 Rescue the Rabbit(AC自动机+状压DP)
Codeforces 86C Genetic engineering(AC自动机+DP)
POJ1699 Best Sequence(AC自动机+状压DP)