学习了字典树之后,来学一下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));
}
}