hdu_2222_Keywords Search(AC自动机板子)

来源:互联网 发布:js数组与字符串比较 编辑:程序博客网 时间:2024/06/04 19:50

题目连接: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=10001*50,tyn=26;//数量乘串长,类型数量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]=0;memset(tr[tot],-1,sizeof(tr[tot]));}    void init(){tot=-1,fail[0]=-1,nw();}    void insert(char *s,int x=0){        for(int len=strlen(s),i=0,w;i<len;x=tr[x][w],i++)            if(tr[x][w=getid(s[i])]==-1)nw(),tr[x][w]=tot;        cnt[x]++;//串尾标记    }    void build(int head=1,int tail=0){        for(Q[++tail]=0;head<=tail;){            for(int i=0,x=Q[head++],p=-1;i<tyn;i++)if(~tr[x][i]){                if(x==0)fail[tr[0][i]]=0;                else for(p=fail[x],fail[tr[x][i]]=0;~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=0){        for(int len=strlen(s),w,i=0,x=0,j;i<len;i++){            while(tr[x][w=s[i]-'a']==-1&&x)x=fail[x];            x=tr[x][w],x=(~x)?x:0,j=x;//加cnt后标记为0,防止重复计数            while(j&&cnt[j])ans+=cnt[j],cnt[j]=0,j=fail[j];        }        return ans;    }}AC;char buf[1000010];int main(){    int t,n;    scanf("%d",&t);    while(t--){        scanf("%d",&n);        AC.init();        F(i,1,n)scanf("%s",buf),AC.insert(buf);        AC.build();        scanf("%s",buf);        printf("%d\n",AC.ask(buf));    }    return 0;}


0 0