[洛谷P3808]【模板】AC自动机(简单版)
题目大意:给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。
题解:AC自动机
卡点:无
C++ Code:
#include <cstdio>
#include <queue>
#include <cstring>
#define maxn 1000010
using namespace std;
int n;
char s[maxn];
int nxt[maxn][26], fail[maxn], cnt[maxn], tot;
int root = 0;
queue<int> q;
void add(char *s) {
int now = root, len = strlen(s);
for (int i = 0; i < len; i++) {
if (nxt[now][s[i] - 'a']) now = nxt[now][s[i] - 'a'];
else now = nxt[now][s[i] - 'a'] = ++tot;
}
cnt[now]++;
}
void build() {
for (int i = 0; i < 26; i++)
if (nxt[root][i]) fail[nxt[root][i]] = root, q.push(nxt[root][i]);
while (!q.empty()) {
int x = q.front(); q.pop();
for (int i = 0; i < 26; i++) {
if (nxt[x][i]) fail[nxt[x][i]] = nxt[fail[x]][i], q.push(nxt[x][i]);
else nxt[x][i] = nxt[fail[x]][i];
}
}
}
int ask(char *s) {
int now = root, ans = 0, len = strlen(s);
for (int i = 0; i < len; i++) {
now = nxt[now][s[i] - 'a'];
for (int j = now; j && ~cnt[j]; j = fail[j]) ans += cnt[j], cnt[j] = -1;
}
return ans;
}
int main() {
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%s", s);
add(s);
}
build();
scanf("%s", s);
printf("%d\n", ask(s));
return 0;
}

浙公网安备 33010602011771号