zoukankan      html  css  js  c++  java
  • bzoj 4827: [Hnoi2017]礼物

    枚举对一个环整体加上的值c=-m~m,则答案

    $sum_{i=0}^{n-1}{(a_i-b_{(i+d)\%n}+c)^2}$

    $=sum_{i=0}^{n-1}{(a_i^2+b_i^2+c^2-2cb_i+2ca_i-2a_ib_{(i+d)\%n})}$

    其中只有$sum_{i=0}^{n-1}{a_ib_{(i+d)\%n}}$一项不能直接计算,但可以看出这是循环卷积的形式,用fft求出对每个d的答案,再取最大值即可

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #define G *++ptr
    char buf[2000000],*ptr=buf-1;
    int _(){
        int x=0,c=G;
        while(c<48)c=G;
        while(c>47)x=x*10+c-48,c=G;
        return x;
    }
    const int M=133333;
    const double _2pi=acos(-1)*2;
    struct cplx{
        double a,b;
        cplx(double _a=0,double _b=0):a(_a),b(_b){}
        cplx operator+(cplx x){return cplx(a+x.a,b+x.b);}
        cplx operator-(cplx x){return cplx(a-x.a,b-x.b);}
        cplx operator*(cplx x){return cplx(a*x.a-b*x.b,a*x.b+b*x.a);}
    }A[M],B[M],e[2][M];
    int N,P;
    int n,m,r[M],a[50007],b[50007],a2=0,a1=0,b2=0,b1=0,ans=0x7fffffff,ab=0;
    void dft(cplx*a,int t){
        for(int i=0;i<N;++i)if(i<r[i])std::swap(a[i],a[r[i]]);
        for(int i=1;i<N;i<<=1){
            for(int j=0,z=N/(i<<1);j<N;j+=i<<1){
                cplx*b=a+j,*c=b+i;
                for(int k=0;k<i;++k){
                    cplx x=b[k],y=c[k]*e[t][k*z];
                    b[k]=x+y;
                    c[k]=x-y;
                }
            }
        }
        if(t)for(int i=0;i<N;++i)a[i].a/=N;
    }
    int main(){
        fread(buf,1,sizeof(buf),stdin)[buf]=0;
        n=_();m=_();
        for(int i=0;i<n;++i)a[i]=_(),a2+=a[i]*a[i],a1+=a[i];
        for(int i=0;i<n;++i)b[i]=_(),b2+=b[i]*b[i],b1+=b[i];
        for(N=2,P=0;N<n*2+3;N<<=1,++P);
        for(int i=1;i<N;++i)r[i]=r[i>>1]>>1|(i&1)<<P;
        for(int i=0;i<N;++i){
            e[0][i]=cplx(cos(i*_2pi/N),sin(i*_2pi/N));
            e[1][i]=cplx(cos(i*_2pi/N),-sin(i*_2pi/N));
        }
        for(int i=0;i<n;++i)A[i]=a[n-1-i],B[i]=b[i];
        dft(A,0);dft(B,0);
        for(int i=0;i<N;++i)A[i]=A[i]*B[i];
        dft(A,1);
        for(int i=n;i<n*2;++i){
            int v=int(A[i].a+A[i-n].a+0.49);
            if(v>ab)ab=v;
        }
        for(int c=-m;c<=m;++c){
            int v=a2+b2+c*c*n-2*b1*c+2*a1*c-2*ab;
            if(v<ans)ans=v;
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    remove white space from read
    optimize the access speed of django website
    dowload image from requests
    run jupyter from command
    crawl wechat page
    python version 2.7 required which was not found in the registry windows 7
    health
    alternate rows shading using conditional formatting
    word
    【JAVA基础】static 关键字
  • 原文地址:https://www.cnblogs.com/ccz181078/p/6727686.html
Copyright © 2011-2022 走看看