• [bzoj3160]万径人踪灭


    传送门

    Description

    Solution 

    可以先求出所有满足条件(1)和条件(2)的子序列

    然后减去其中不满足条件(3)的,也就是回文子串的数量

    对于第一步,可以用(NTT)先求出每根对称轴有多少个位置与它对称,设为(x)

    [x-a=b-x\ ightarrow a+b=2x ]

    然后每个对称轴就有(2^{x}-1)的贡献

    对于第二步,可以用manacher直接计算


    Code 

    /**************************************************************
        Problem: 3160
        User: PaperCloud
        Language: C++
        Result: Accepted
        Time:7748 ms
        Memory:15648 kb
    ****************************************************************/
     
    #include<bits/stdc++.h>
    #define min(a,b) ((a)<(b)?(a):(b))
    #define max(a,b) ((a)>(b)?(a):(b))
    #define reg register
    #define ll long long
    #define db double
    #define int ll
    #define PaperCloud FallDream
    const int Mod=998244353,g=3,invg=332748118,P=1e9+7;
    int Mul(int a,int b,int M=Mod){return (1ll*a*b)%M;}
    int Add(int a,int b,int M=Mod){return (a+b)%M;}
    int fpow(int a,int b,int M=Mod){int r=1;for(;b;b>>=1,a=Mul(a,a,M))if(b&1)r=Mul(r,a,M);return r;}
    void NTT(int *a,int N,int ty,int *pos)
    {
        int w,wn,i,j,p,k,X,Y;
        for(i=0;i<N;++i) if(pos[i]>i) std::swap(a[i],a[pos[i]]);
        for(i=1;i<N;i<<=1)
        {
            w=fpow(ty>0?g:invg,(Mod-1)/(i<<1));
            for(j=0,p=(i<<1);j<N;j+=p)
                for(wn=1,k=0;k<i;++k,wn=Mul(wn,w))
                {
                    X=a[j+k],Y=Mul(a[j+i+k],wn);
                    a[j+k]=Add(X,Y);a[j+i+k]=Add(X,Mod-Y);
                }
        }
        if(ty==-1)for(j=fpow(N,Mod-2),i=0;i<N;++i)a[i]=Mul(a[i],j);
    }
    const int MN=1e5+5;
    char s[MN*3];
    int a[2][MN*5],p[MN*3],ans,pos[MN*5];
    int Calc(int len)
    {
        s[len*2+1]='$';
        for(int i=len;i;--i) s[i*2]=s[i-1],s[i*2-1]='$';
        s[0]='*';
        int mx=0,id=0;
        for(int i=1;i<=(len<<1);++i)
        {
            p[i]=mx>i?min(p[id*2-i],mx-i):1;
            while(s[i+p[i]]==s[i-p[i]])++p[i];
            if(i+p[i]>mx)id=i,mx=p[i]+i;
        }
        ll r=0;
        for(int i=1;i<=(len<<1);++i) r=Add(r,p[i]/2,P);
        return r;
    }
    signed main()
    {
        scanf("%s",s);
        int len=strlen(s);
        int N,i,j;
        for(N=1;N<len*2;N<<=1);
        memset(a,0,sizeof a);
        for(i=0;i<len;++i) a[s[i]=='b'][i]=1;
        for(i=0;i<N;++i) pos[i]=(pos[i>>1]>>1)|((i&1)*(N>>1));
    //  for(i=0;i<len*2-1;++i) printf("%d : %d %d 
    ",i,a[0][i],a[1][i]);
        for(i=0;i<2;++i)
        {
            NTT(a[i],N,1,pos);
            for(j=0;j<N;++j) a[i][j]=Mul(a[i][j],a[i][j]);
            NTT(a[i],N,-1,pos);
        }
        for(i=0;i<len*2-1;++i) ans=Add(ans,Add(fpow(2,(a[0][i]+1)/2+(a[1][i]+1)/2,P),P-1,P),P);
    //  printf("%d
    ",ans);
        ans=Add(ans,P-Calc(len),P);
        return 0*printf("%lld
    ",ans);
    }
    


    Blog来自PaperCloud,未经允许,请勿转载,TKS!

  • 相关阅读:
    将Apache2.4手动安装成Windows的服务
    [译文]PHP千年虫(y2k compliance)
    Apache2.4 authz_core_module模块使用
    Cannot start session without errors, please check errors given in your PHP and/or webserver log file and configure your PHP installation properly.错误
    [转载]开启debug调试模式
    thinkphp 去掉URL 里面的index.php
    在WINDOWS下安装PEAR
    php5.5.15注释问题PHP Deprecated: Comments starting with '#' are deprecated in *.ini 警告解决办法
    Maven 与 IntelliJ IDEA 的完美结合
    JavaRebel 2.0 发布,一个JVM插件
  • 原文地址:https://www.cnblogs.com/PaperCloud/p/11181774.html
Copyright © 2020-2023  润新知