hdu_2222_Keywords Search(AC自动机板子)

时间:2023-03-09 18:25:04
hdu_2222_Keywords Search(AC自动机板子)

题目连接:hdu_2222_Keywords Search

存个自己写的AC自动机

 #include<cstdio>
#include<cstring>
#define F(i,a,b) for(int i=a;i<=b;i++) const int AC_N=*,tyn=;//数量乘串长,类型数量
struct AC_automation{
int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot;
inline int getid(char x){return x-'a';}
void nw(){cnt[++tot]=;memset(tr[tot],-,sizeof(tr[tot]));}
void init(){tot=-,fail[]=-,nw();}
void insert(char *s,int x=){
for(int len=strlen(s),i=,w;i<len;x=tr[x][w],i++)
if(tr[x][w=getid(s[i])]==-)nw(),tr[x][w]=tot;
cnt[x]++;//串尾标记
}
void build(int head=,int tail=){
for(Q[++tail]=;head<=tail;){
for(int i=,x=Q[head++],p=-;i<tyn;i++)if(~tr[x][i]){
if(x==)fail[tr[][i]]=;
else for(p=fail[x],fail[tr[x][i]]=;~p;p=fail[p])
if(~tr[p][i]){fail[tr[x][i]]=tr[p][i];break;}
Q[++tail]=tr[x][i];
}
}
}
int ask(char *s,int ans=){
for(int len=strlen(s),w,i=,x=,j;i<len;i++){
while(tr[x][w=s[i]-'a']==-&&x)x=fail[x];
x=tr[x][w],x=(~x)?x:,j=x;//加cnt后标记为0,防止重复计数
while(j&&cnt[j])ans+=cnt[j],cnt[j]=,j=fail[j];
}
return ans;
}
}AC;
char buf[];
int main(){
int t,n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
AC.init();
F(i,,n)scanf("%s",buf),AC.insert(buf);
AC.build();
scanf("%s",buf);
printf("%d\n",AC.ask(buf));
}
return ;
}