zoukankan      html  css  js  c++  java
  • 【BZOJ3160】 万径人踪灭(FFT,manacher)

    前言

    多项式真的很难♂啊qwq

    Solution

    考虑求的是一个有间隔的回文串,相当于是:
    总的答案-没有间隔的答案

    考虑总的答案怎么计算?FFT卷一下就好了。
    对于每一位字符,有两种取值,然后随便卷起来,卷起来就是当前这一位之前与它相同的字符个数(这一位不能是‘0’,也就是被排斥的那一位)
    然后就可以轻松解决?
    是的。

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<iostream>
    #include<queue>
    #include<algorithm>
    #include<complex>
    #define ll long long
    #define re register
    using namespace std;
    inline int gi(){
        int f=1,sum=0;char ch=getchar();
        while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
        return f*sum;
    }
    const int maxn=2000010,Mod=1e9+7;
    const double Pi=acos(-1.0);
    char s[maxn];
    int len,N,M,p[maxn],r[maxn];
    ll f[maxn],tw[maxn],ans;
    complex<double>a[maxn],b[maxn];
    ll manacher(){
        s[len+len+1]='#';s[0]=' ';
        for(int i=len;i;i--){
            s[i*2]=s[i];s[i*2-1]='#';
        }
        int mx=0,id=0;
        for(int i=1;i<=len+len;i++){
            p[i]=mx>i?min(p[id*2-i],mx-i):1;
            while(s[p[i]+i]==s[i-p[i]])p[i]++;
            if(i+p[i]>mx){
                id=i;mx=i+p[i];
            }
        }
        ll ret=0;
        for(int i=1;i<=len+len;i++)
            ret=(ret+p[i]/2)%Mod;
        return ret;
    }
    void FFT(complex<double> *P,int opt)
    {
        for(int i=0;i<N;++i)if(i<r[i])swap(P[i],P[r[i]]);
        for(int i=1;i<N;i<<=1)
        {
            complex<double> W(cos(Pi/i),opt*sin(Pi/i));
            for(int p=i<<1,j=0;j<N;j+=p)
            {
                complex<double> w(1,0);
                for(int k=0;k<i;++k,w*=W)
                {
                    complex<double> X=P[j+k],Y=P[i+j+k]*w;;
                    P[j+k]=X+Y;P[i+j+k]=X-Y;
                }
            }
        }
    }
    void work(char cc)
    {
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        for(int i=1;i<=len;++i)a[i]=b[i]=s[i]==cc;
        FFT(a,1);FFT(b,1);
        for(int i=0;i<N;++i)a[i]*=b[i];
        FFT(a,-1);
        for(int i=1;i<N;++i)a[i].real()=a[i].real()/N+0.5;
        for(int i=0;i<=M;++i)f[i]+=((int)(a[i].real())+1)/2;
    }
    int main(){
        scanf("%s",s+1);len=strlen(s+1);
        M=len+len;tw[0]=1;
        for(int i=1;i<=M;i++)tw[i]=(tw[i-1]+tw[i-1])%Mod;
        int l=0;
        for(N=1;N<=M;N<<=1)l++;
        for(int i=0;i<N;i++)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
        work('a');work('b');
        for(int i=1;i<=M;i++)ans=(ans+tw[f[i]]-1)%Mod;
        printf("%lld
    ",(ans-manacher()+Mod)%Mod);
        return 0;
    }
    
  • 相关阅读:
    LightOJ 1344 Aladdin and the Game of Bracelets
    CF 1132A,1132B,1132C,1132D,1132E,1132F(Round 61 A,B,C,D,E,F)题解
    CF 1130A 1130B 1130C1129A1 1129A2 1129B(Round542A B C D1 D2 E)题解
    CF 1131A,1131B,1131C,1131D,1131F(Round541 A,B,C,D,F)题解
    CoderForces-Round60D(1117) Magic Gems
    CoderForces Round60-(1117A,1117B,1117C题解)
    LightOJ 1038 Race To 1 Again(概率DP)
    XHXJ'S LIS(数位DP)
    CF 55D Beautiful Numbers(数位DP)
    LightOJ 1229 Tablecross
  • 原文地址:https://www.cnblogs.com/mleautomaton/p/10278236.html
Copyright © 2011-2022 走看看