AC自动机模板。首先定义一个功能很强大的结构体,里边包含有关的所有的应用,再对文章进行多模式匹配。
#include <iostream>
#include <stdio.h>
#include <queue>
#include <string>
#include <memory.h>
using namespace std;
const int maxn = 500010;
char str[1000010];
struct ACAutomation
{
int ch[maxn][26],val[maxn],last[maxn],fail[maxn],sz,root;
int newnode(){
memset(ch[sz],0,sizeof(ch[sz]));
val[sz] = 0;
return sz ++;
}
void init(){
sz = 0;
root = newnode();
}
void insrt(char *str){
int len = strlen(str);
int now = root;
for(int i = 0;i < len;i ++){
int &tmp = ch[now][str[i] - 'a'];
if(!tmp) tmp = newnode();
now = tmp;
}
val[now] ++;
}
void getfail(){
queue<int> q;
fail[root] = root;
for(int i = 0;i < 26;i ++){
int u = ch[root][i];
if(u){
fail[u] = last[u] = 0;
q.push(u);
}
}
while(!q.empty()){
int now = q.front();q.pop();
for(int i = 0;i < 26;i ++){
int u = ch[now][i];
if(!u) ch[now][i] = ch[fail[now]][i];
else{
fail[u] = ch[fail[now]][i];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
q.push(u);
}
}
}
}
int query(char *str){
int len = strlen(str);
int now = root;
int ret = 0;
for(int i = 0;i < len;i++){
now = ch[now][str[i]-'a'];
int tmp = now;
while(tmp != root && val[tmp]){
ret += val[tmp];
val[tmp] = 0;
tmp = last[tmp];
}
}
return ret;
}
}cat;
int main()
{
int T,n;scanf("%d",&T);
while(T --){
cat.init();
scanf("%d",&n);
for(int i = 0;i < n;i ++){
scanf("%s",str);
cat.insrt(str);
}
cat.getfail();
scanf("%s",str);
printf("%d\n",cat.query(str));
}
return 0;
}