题意
给定n个模式串,求目标串中出现了多少个模式串。
思路
AC自动机模版题。
Code
#include <bits/stdc++.h> using namespace std; const int maxn = 1e6+10; struct Ac { int tr[maxn][26], fail[maxn], e[maxn], cnt[maxn]; int tot; void init() { memset(tr, 0, sizeof(tr)); memset(e, 0, sizeof(e)); memset(cnt, 0, sizeof(cnt)); memset(fail, 0, sizeof(fail)); tot=0; } void insert(char *t) { int p=0; for (int c, i=0; t[i]; ++i) { c = t[i]-'a'; if(!tr[p][c]) tr[p][c] = ++tot; p=tr[p][c]; } ++e[p]; } void build() { queue<int>q; for (int i=0; i<26; ++i) { if(tr[0][i]) q.push(tr[0][i]); } while(!q.empty()) { int u=q.front(); q.pop(); for (int i=0; i<26; ++i) { if(tr[u][i]) fail[tr[u][i]]=tr[fail[u]][i], q.push(tr[u][i]); else tr[u][i]=tr[fail[u]][i]; } } } int query(char *t) { int p=0, res=0; for (int i=0; t[i]; ++i) { p = tr[p][t[i]-'a']; for (int j=p; j && e[j]!=-1; j=fail[j]) { res += e[j]; e[j]=-1; } } return res; } }ac; int n, T; char str[maxn]; int main() { scanf("%d", &T); while(T--) { scanf("%d", &n); ac.init(); for (int i=1; i<=n; ++i) { scanf("%s", str); ac.insert(str); } scanf("%s", str); ac.build(); printf("%d\n", ac.query(str)); } return 0; }