zoukankan      html  css  js  c++  java
  • hdu 6096 String(AC自动机巧妙建图)

    题目链接:hdu 6096 String

    题意:

    给你n个字符串,和q个询问,每个询问给出一个前缀和后缀,问你在这n个字符串中有多少个包含给出的询问,前缀和后缀不能重叠。

    题解:

    比赛的时候用的hash,无限wa,然后下来后发现他有一组特别的数据专卡我的hash,随便怎么换种子都能卡。真是R了狗了。

    然后这题有一个巧妙的办法,用AC自动机去跑。

    比如待匹配串是abc,abcd,那么我们将它们转换为abc#abc,abcd#abcd,

    然后询问是a c  ab cd ,那么就将询问转换为c#a cd#ab。

    然后将询问插进AC自动机,将每个带匹配串拿去匹配一下,顺便判断一下长度就行了。

     1 #include<bits/stdc++.h>
     2 #define mst(a,b) memset(a,b,sizeof(a))
     3 #define F(i,a,b) for(int i=(a);i<=(b);++i)
     4 using namespace std;
     5 typedef pair<int,int>P;
     6 
     7 const int N=5e5+7;
     8 const int AC_N=N,tyn=27;
     9 int ans[N],t,n,q,ed,mp[N];
    10 char str[N],pre[N],suf[N];
    11 P s[N];
    12 struct AC_automation{
    13     int tr[AC_N][tyn],Q[AC_N],fail[AC_N],tot;
    14     int cnt[AC_N];
    15     inline int getid(char x){return x=='#'?26:x-'a';}
    16     void nw(){cnt[++tot]=0,fail[tot]=0;memset(tr[tot],0,sizeof(tr[tot]));}
    17     void init(){tot=-1,fail[0]=-1,nw();}
    18     int insert(char *s,int len,int x=0){
    19         for(int i=0,w;s[i];x=tr[x][w],i++)
    20             if(!tr[x][w=getid(s[i])])nw(),tr[x][w]=tot;
    21         cnt[x]=len;
    22         return x;
    23     }
    24     void build(int head=1,int tail=0){
    25         for(int i=0;i<tyn;i++)if(tr[0][i])Q[++tail]=tr[0][i];
    26         while(head<=tail)for(int x=Q[head++],i=0;i<tyn;i++)
    27             if(tr[x][i])fail[tr[x][i]]=tr[fail[x]][i],Q[++tail]=tr[x][i];
    28             else tr[x][i]=tr[fail[x]][i];
    29     }
    30     void ask(char *s,int len){
    31         for(int x=0,i=0,w,j;s[i];i++){
    32             x=tr[x][w=getid(s[i])];
    33             for(j=x;j;j=fail[j])if(cnt[j]&&cnt[j]<=len)ans[j]++;
    34         }
    35     }
    36 }AC;
    37 
    38 
    39 int main(){
    40     scanf("%d",&t);
    41     while(t--)
    42     {
    43         scanf("%d%d",&n,&q);
    44         AC.init();mst(ans,0);ed=0;
    45         F(i,1,n)
    46         {
    47             scanf("%s",str+ed);
    48             int len=strlen(str+ed);
    49             s[i]=P(ed,len),ed+=len;
    50         }
    51         F(i,1,q)
    52         {
    53             scanf("%s%s",pre,suf);
    54             strcat(suf,"#");
    55             strcat(suf,pre);
    56             mp[i]=AC.insert(suf,strlen(suf)-1);
    57         }
    58         AC.build();
    59         F(i,1,n)
    60         {
    61             int st=s[i].first,en=st+s[i].second;
    62             F(i,st,en)pre[i-st]=suf[i-st]=str[i];
    63             pre[s[i].second]=suf[s[i].second]=0;
    64             strcat(pre,"#");
    65             strcat(pre,suf);
    66             AC.ask(pre,s[i].second);
    67         }
    68         F(i,1,q)printf("%d
    ",ans[mp[i]]);
    69     }
    70     return 0;
    71 }
    View Code
  • 相关阅读:
    JSON
    css3之自定义字体
    css3之2D转换
    JavaScript---认识JavaScipt
    学JS必看-JavaScript数据结构深度剖析
    Vue 过渡
    Vue 表单控件绑定
    Vue 方法与事件处理器
    Vue 列表渲染
    Vue 条件渲染
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7345663.html
Copyright © 2011-2022 走看看