题意
给定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
", ac.query(str));
}
return 0;
}