学习了字典树之后,来学一下AC自动机,其实挺简单的,但是很强大
这是一道AC自动机模板题
AC自动机学习博客:​​ac自动机最详细的讲解,让你一次学会ac自动机。​​

我的代码:

#include<cstdio>
#include<cstring>
using namespace std;

const int maxn=500000+100;

int trie[maxn][26],sum[maxn],fail[maxn],tot;
int que[maxn];

inline void insert(char* ch){

int len=strlen(ch);
int root=0;
for(int i=0;i<len;i++){

int ind=ch[i]-'a';
if(!trie[root][ind]) trie[root][ind]=++tot;
root=trie[root][ind];
}
sum[root]++;
}

inline void build_fail(){

int l=0;
int r=1;
que[l]=0; // que[l]=root=0
while(l<r){

int tmp=que[l++];
for(int i=0;i<=25;i++){

int node=trie[tmp][i];
if(node){

if(tmp==0){

fail[node]=0;
}
else{

int node_tmp=fail[tmp];
while(!trie[node_tmp][i] && node_tmp){

node_tmp=fail[node_tmp];
}
if(trie[node_tmp][i]) fail[node]=trie[node_tmp][i];
else fail[node]=0;
}
que[r++]=node;
}
}
}
}

inline int search(char* ch){

int len=strlen(ch);
int root=0;
int cnt=0;
for(int i=0;i<len;i++){

int ind=ch[i]-'a';
while(!trie[root][ind] && root) root=fail[root];
root=trie[root][ind];
if(root){

int node_tmp=root;
while(node_tmp){

if(sum[node_tmp]>=0){

cnt+=sum[node_tmp];
sum[node_tmp]=-1;
}
else break;
node_tmp=fail[node_tmp];
}
}
}
return cnt;
}

inline void init(){

tot=0;
memset(trie,0,sizeof(trie));
memset(sum,0,sizeof(sum));
memset(fail,0,sizeof(fail));
}

char str[maxn*2];

int main(){

int T,n;
scanf("%d",&T);
while(T--){

init();
scanf("%d",&n);
getchar();
char ch[100];
for(int i=1;i<=n;i++){

scanf("%s",ch);
insert(ch);
}
build_fail();
scanf("%s",str);
printf("%d\n",search(str));
}
}