zoukankan      html  css  js  c++  java
  • LG P4199 万径人踪灭

    Description

    在只含a,b的字符串中,求满足以下条件的子序列个数:

    • 位置和字符关于某条对称轴对称
    • 不能是连续的一段

    Solution

    答案可以转化为关于某条对称轴对称的子序列-连续的回文串

    连续的回文串可以用Manacher求出

    关于某条对称轴对称的子序列可以FFT求出:将原字符串中为a的位置设为1,b的位置设为0,该多项式自平方后第$i$位即为以$frac{i}{2}$为对称轴,左右两边相同位置为a的对数$x$,b同理,则分奇偶讨论可得以该对称轴为中心有$2^{x+1}-1$或$2^x-1$个字母组合满足条件

    FFT多项式相乘

    #include<iostream>
    #include<cstring>
    #include<complex>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    long long len,rev[400005],tot=1,s=2,ans[400005],r[400005],sum;
    const long long mod=1000000007;
    const double pi=acos(-1);
    char str[400005],sn[400005];
    complex<double>an[400005],bn[400005];
    inline long long read()
    {
        long long w=0,f=1;
        char ch=0;
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            w=(w<<1)+(w<<3)+ch-'0';
            ch=getchar();
        }
        return w*f;
    }
    void fft(complex<double>*a,long long n,long long inv)
    {
        for(long long i=0;i<n;i++)
        {
            if(i<rev[i])
            {
                swap(a[i],a[rev[i]]);
            }
        }
        for(long long i=1;i<n;i<<=1)
        {
            complex<double>wn=exp(complex<double>(0,inv*pi/i));
            for(long long j=0;j<n;j+=i*2)
            {
                complex<double>w(1,0);
                for(long long k=j;k<i+j;k++)
                {
                    complex<double>x=a[k],y=w*a[k+i];
                    a[k]=x+y;
                    a[k+i]=x-y;
                    w*=wn;
                }
            }
        }
        if(inv==-1)
        {
            for(long long i=0;i<n;i++)
            {
                a[i]/=n;
            }
        }
    }
    long long ksm(long long a,long long p)
    {
        long long ret=1ll;
        while(p)
        {
            if(p&1)
            {
                (ret*=a)%=mod;
            }
            (a*=a)%=mod;
            p>>=1;
        }
        return ret;
    }
    void manacher()
    {
        long long nlen=0,maxx=0,maxlen=-1,id;
        sn[nlen]='$';
        sn[++nlen]='#';
        for(long long i=0;i<len;i++)
        {
            sn[++nlen]=str[i];
            sn[++nlen]='#';
        }
        sn[++nlen]='';
        for(long long i=1;i<=nlen;i++)
        {
            if(i<maxx)
            {
                r[i]=min(r[2*id-i],maxx-i);
            }
            else
            {
                r[i]=1;
            }
            while(sn[i-r[i]]==sn[i+r[i]])
            {
                ++r[i];
            }
            if(maxx<i+r[i])
            {
                maxx=i+r[i];
                id=i;
            }
            ((sum-=(r[i]>>1))+=mod)%=mod;
        }
    }
    int main()
    {
        scanf("%s",str);
        len=strlen(str);
        for(long long i=0;i<len;i++)
        {
            an[i]=(double)(str[i]=='a');
            bn[i]=(double)(str[i]=='b');
        }
        while((1<<tot)<(len<<1))
        {
            ++tot;
            s<<=1;
        }
        for(long long i=0;i<s;i++)
        {
            rev[i]=(rev[i>>1]>>1)|((i&1)<<(tot-1));
        }
        fft(an,s,1);
        fft(bn,s,1);
        for(long long i=0;i<s;i++)
        {
            an[i]*=an[i];
            bn[i]*=bn[i];
        }
        fft(an,s,-1);
        fft(bn,s,-1);
        for(long long i=0;i<s;i++)
        {
            ans[i]+=(long long)(an[i].real()+0.5);
            ans[i]+=(long long)(bn[i].real()+0.5);
            if(!(i&1))
            {
                ++ans[i];
            }
            ans[i]>>=1;
        }
        for(long long i=0;i<=2*len-2;i++)
        {
            ans[i]=ksm(2,ans[i])-1;
        }
        manacher();
        for(long long i=0;i<=2*len-2;i++)
        {
            (sum+=ans[i])%=mod;
        }
        printf("%lld
    ",sum);
        return 0;
    }
    万径人踪灭
  • 相关阅读:
    【ZBar】ios错误ignoring file xxx missing required architecture x86_64 in file
    微信内置浏览器UserAgent的判断
    运维技能大全 | Devops Tools 周期表
    Mysql 常用命令集
    Iphone H5上传照片被旋转
    陈小春 相依为命
    Hiveserver2 OOM问题解法
    hiveserver 占用内存过大的问题
    linux查看CPU和内存使用情况
    linux Shell函数
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/13499550.html
Copyright © 2011-2022 走看看