题目大意:给定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 ", ask(s)); return 0; }