• 洛咕 P4199 万径人踪灭


    给了两条限制,但是第二条想想是没用的,直接manacher就可以减掉多余的部分了,所以要求满足第一条的方案

    也不难,可以想到枚举每个中心点,计算两边有多少对距离中心相等的位置值也相等,假设有(t)个,那么以这个中心点为半径的就是(2^t-1),因为每个都可以选或不选,减去全都不选的情况

    现在就要计算和每个中心点距离相等的位置对数了,显然两个位置(a,b)如果值相同,那么中心就是((a+b)/2)(如果是小数的话就是两个格子之间的)

    所以就简单了,(A(i)=[S[i]='a'],B(i)=[S[i]='b']),这两个多项式分别平方一下,然后再算(2^x-1),所有这些之和就是满足第一条的方案了

    #include<bits/stdc++.h>
    #define il inline
    #define vd void
    #define mod 1000000007
    typedef long long ll;
    il int gi(){
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')f=-1;
            ch=getchar();
        }
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    const double pi=acos(-1);
    struct cp{
        double real,imag;
        cp(){}
        cp(const double&r,const double&i){real=r,imag=i;}
        il cp conj(){return(cp){real,-imag};}
        il vd operator =(const double&b){real=b,imag=0;}
    };
    il cp operator +(const cp&a,const cp&b){return(cp){a.real+b.real,a.imag+b.imag};}
    il cp operator -(const cp&a,const cp&b){return(cp){a.real-b.real,a.imag-b.imag};}
    il cp operator *(const cp&a,const cp&b){return(cp){a.real*b.real-a.imag*b.imag,a.real*b.imag+a.imag*b.real};}
    char S[200010];
    int rev[1<<19];
    cp A[1<<19],omg[1<<19],inv[1<<19];
    il vd fft(cp*A,int n,cp*omg){
        for(int i=0;i<n;++i)if(rev[i]>i)std::swap(A[i],A[rev[i]]);
        for(int o=1;o<n;o<<=1)
            for(cp*p=A;p!=A+n;p+=o<<1)
                for(int i=0;i<o;++i){
                    cp t=omg[n/(o<<1)*i]*p[i+o];
                    p[i+o]=p[i]-t,p[i]=p[i]+t;
                }
    }
    int t[200010];
    il int pow(int x,int y){
        int ret=1;
        while(y){
            if(y&1)ret=1ll*ret*x%mod;
            x=1ll*x*x%mod;y>>=1;
        }
        return ret;
    }
    int r[200010];
    int main(){
        scanf("%s",S+1);int n=strlen(S+1);
        int N=1,lg=0;while(N<(n+2)<<1)N<<=1,++lg;
        for(int i=0;i<N;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<lg-1);
        for(int i=0;i<N;++i)omg[i]=cp(cos(i*2*pi/N),sin(i*2*pi/N)),inv[i]=omg[i].conj();
        for(int i=1;i<=n;++i)A[i]=S[i]=='a';
        fft(A,N,omg);
        for(int i=0;i<N;++i)A[i]=A[i]*A[i];
        fft(A,N,inv);
        for(int i=1;i<=n<<1;++i)t[i]=(int)(A[i].real/N+0.5);
        for(int i=0;i<N;++i)A[i]=0;
        for(int i=1;i<=n;++i)A[i]=S[i]=='b';
        fft(A,N,omg);
        for(int i=0;i<N;++i)A[i]=A[i]*A[i];
        fft(A,N,inv);
        for(int i=1;i<=n<<1;++i)t[i]+=(int)(A[i].real/N+0.5);
        ll ans=0;
        for(int i=1;i<=n<<1;++i)t[i]=t[i]/2+!(i&1),ans+=pow(2,t[i])-1;
        for(int i=n;i;--i)S[i<<1]=S[i];
        N=n<<1|1;
        for(int i=1;i<=N;i+=2)S[i]='#';
        S[0]='s',S[N+1]='t';
        int R=1,mid=1;r[1]=1;
        for(int i=2;i<=N;++i){
            r[i]=1;
            if(i<=R)r[i]=std::min(R-i+1,r[mid*2-i]);
            while(S[i-r[i]]==S[i+r[i]])++r[i];
            if(i+r[i]-1>R)mid=i,R=i+r[i]-1;
        }
        for(int i=1;i<=N;++i)ans-=r[i]>>1;
        printf("%lld
    ",(ans%mod+mod)%mod);
        return 0;
    }
    
  • 相关阅读:
    SSAS 内部错误:操作未能成功
    无法从项目中获取SSIS包的列表
    新特技软件(Analyzer)添加新用户
    cmd命令搜集
    面试中--js注意事项(小知识点)
    面试的一般需求
    函数----let和const
    函数----箭头函数
    vuex的相关知识
    js中,数组去重的方法的总结(温故而知新)
  • 原文地址:https://www.cnblogs.com/xzz_233/p/10060669.html
Copyright © 2020-2023  润新知