题解
AC自动机
代码
#include <bits/stdc++.h>
using namespace std;
const int nmax = 1e6 + 7;
const int sigma = 26;
struct Aho {
int sz;
queue<int> que;
struct Node {
int nxt[sigma];
int cnt, fail;
} node[nmax];
void init() {
while(!que.empty()) que.pop();
memset(node, 0, sizeof node);
sz = 1;
}
inline int idx(const char & ch) {return ch - 'a';}
void insert(char * S) {
int len = strlen(S);
int now = 0;
for(int i = 0; i < len; ++i) {
char ch = S[i];
if(!node[now].nxt[idx(ch)])
node[now].nxt[idx(ch)] = sz++;
now = node[now].nxt[idx(ch)];
}
node[now].cnt ++;
}
void build_fail() {
node[0].fail = -1;
que.push(0);
while(!que.empty()) {
int u = que.front(); que.pop();
for(int i = 0; i < sigma; ++i) {
if(node[u].nxt[i]) {
if(u == 0) node[node[u].nxt[i]].fail = 0;
else {
int v = node[u].fail;
while(v != -1) {
if(node[v].nxt[i]) {
node[node[u].nxt[i]].fail = node[v].nxt[i];
break;
}
v = node[v].fail;
}
if(v == -1) node[node[u].nxt[i]].fail = 0;
}
que.push(node[u].nxt[i]);
}
}
}
}
int Get(int u) {
int ans = 0;
while(u) {
ans += node[u].cnt;
node[u].cnt = 0;
u = node[u].fail;
}
return ans;
}
int match(char * S) {
int len = strlen(S);
int ans = 0, now = 0;
for(int i = 0; i < len; ++i) {
char ch = S[i];
if(node[now].nxt[idx(ch)])
now = node[now].nxt[idx(ch)];
else {
int fa = node[now].fail;
while(fa != -1 && !node[fa].nxt[idx(ch)]) fa = node[fa].fail;
if(fa == -1) now = 0;
else now = node[fa].nxt[idx(ch)];
}
if(node[now].cnt)
ans += Get(now);
}
return ans;
}
} aho;
int t,n;
char str[nmax];
int main() {
scanf("%d", &t);
while(t--) {
aho.init();
scanf("%d", &n);
for(int i = 0; i < n; ++i) {
scanf("%s", str);
aho.insert(str);
}
aho.build_fail();
scanf("%s",str);
printf("%d\n", aho.match(str));
}
}