AC自动机
没用的AC自动机
问题链接
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1e6 + 5, MM = 10501;
char Sin[N], mstr[151][71];
int DictionaryTree[MM][28], ide, fail[MM];
int W[151], cnt[MM];
void ins(char *str, int n) {
int now(0);
for ( ; *str; ++ str) {
if (!DictionaryTree[now][*str - 'a'])
DictionaryTree[now][*str - 'a'] = ++ ide,
DictionaryTree[ide][27] = now;
now = DictionaryTree[now][*str - 'a'];
}
W[n] = now;
}
int Q[MM], NowIcpy;
void DictionaryTreeClear(int *now = DictionaryTree[0]) {
for (int i(0); i < 26; ++ i) if (now[i]) NowIcpy = now[i], now[i] = 0, DictionaryTreeClear(DictionaryTree[NowIcpy]);
}
void ACautomation(char *str, int n, int iend) {
int now(0), maxn(0);
memset(cnt, 0, 4 * W[n] + 4);
for ( ; *str; ++ str)
++ cnt[now = DictionaryTree[now][*str - 'a']];
for (int i = iend; i; -- i) cnt[fail[Q[i]]] += cnt[Q[i]];
for (int i = n; i; -- i) maxn = max(cnt[W[i]], maxn);
printf("%d\n", maxn);
for (int i = 1; i <= n; ++ i)
if (maxn == cnt[W[i]])
puts(mstr[i]);
DictionaryTreeClear();
memset(fail, 0, 4 * ide + 4), ide = 0;
}
void build(char *str, int n, int iend = 0, int top = 0) {
for (int i(0); i < 26; ++ i) if (DictionaryTree[0][i]) Q[++ iend] = DictionaryTree[0][i];
int* now;
while (top ^ iend) {
now = DictionaryTree[Q[++ top]];
for (char i(0); i < 26; ++ i) {
if (now[i]) fail[now[i]] = DictionaryTree[fail[Q[top]]][i], Q[++ iend] = now[i];
else now[i] = DictionaryTree[fail[Q[top]]][i];
}
}
ACautomation(Sin, n, iend);
}
signed main() {
int n;
while (scanf("%d", &n), n) {
for (int i = 1; i <= n; ++ i) scanf("%s", mstr[i]), ins(mstr[i], i);
scanf("%s", Sin);
build(Sin, n);
}
return 0;
}