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;
    }
  • 相关阅读:
    hdu 4503(湫湫系列故事——植树节)
    JAVA里面如何让一个线程死亡或结束
    c 语言static
    TUXEDO与ORACLE数据库的互连
    关于使用PRO*C编程的一些简单说明和例子
    atoi函数
    我的顶级Java工具名单
    Tuxedo动态配置命令 tmconfig用法总结
    main(argc,argv) 中的参数
    pro c中varchar类型变量的arr函数是做什么用?
  • 原文地址:https://www.cnblogs.com/ccz181078/p/6727686.html
Copyright © 2011-2022 走看看