hdu_2222_Keywords Search(AC自动机板子)

题目连接:hdu_2222_Keywords Search

存个自己写的AC自动机

 1 #include<cstdio>
 2 #include<cstring>
 3 #define F(i,a,b) for(int i=a;i<=b;i++)
 4 
 5 const int AC_N=10001*50,tyn=26;//数量乘串长,类型数量
 6 struct AC_automation{
 7     int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot;
 8     inline int getid(char x){return x-'a';}
 9     void nw(){cnt[++tot]=0;memset(tr[tot],-1,sizeof(tr[tot]));}
10     void init(){tot=-1,fail[0]=-1,nw();}
11     void insert(char *s,int x=0){
12         for(int len=strlen(s),i=0,w;i<len;x=tr[x][w],i++)
13             if(tr[x][w=getid(s[i])]==-1)nw(),tr[x][w]=tot;
14         cnt[x]++;//串尾标记
15     }
16     void build(int head=1,int tail=0){
17         for(Q[++tail]=0;head<=tail;){
18             for(int i=0,x=Q[head++],p=-1;i<tyn;i++)if(~tr[x][i]){
19                 if(x==0)fail[tr[0][i]]=0;
20                 else for(p=fail[x],fail[tr[x][i]]=0;~p;p=fail[p])
21                         if(~tr[p][i]){fail[tr[x][i]]=tr[p][i];break;}
22                 Q[++tail]=tr[x][i];
23             }
24         }
25     }
26     int ask(char *s,int ans=0){
27         for(int len=strlen(s),w,i=0,x=0,j;i<len;i++){
28             while(tr[x][w=s[i]-'a']==-1&&x)x=fail[x];
29             x=tr[x][w],x=(~x)?x:0,j=x;//加cnt后标记为0,防止重复计数
30             while(j&&cnt[j])ans+=cnt[j],cnt[j]=0,j=fail[j];
31         }
32         return ans;
33     }
34 }AC;
35 char buf[1000010];
36 int main(){
37     int t,n;
38     scanf("%d",&t);
39     while(t--){
40         scanf("%d",&n);
41         AC.init();
42         F(i,1,n)scanf("%s",buf),AC.insert(buf);
43         AC.build();
44         scanf("%s",buf);
45         printf("%d
",AC.ask(buf));
46     }
47     return 0;
48 }
View Code



原文地址:https://www.cnblogs.com/bin-gege/p/5696079.html