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

    这个m的范围很有欺骗性啊。。。以为是要枚举C的

    不管C的话其实就是要一个min{sigema (Y(i)-X(i+k))^2 }

    把Y翻转过来,这样旋转k步的圈就是第n+k位

    把它拆开的话其实只要算一个X*Y,就是fft的事儿了

    再看看C怎么处理,我们带着C拆开,那么会多一个这个东西:sigema (x+C-y)*C == (sumx-sumy+C)*C

    C取(sumx-sumy)/n就可以了,保险起见多算几次。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    LL sqr(LL x){return x*x;}
    
    const double pi=acos(-1.0);
    struct complex
    {
        double r,i;
        complex(){}
        complex(double R,double I){r=R,i=I;}
        friend complex operator +(complex x,complex y){return complex(x.r+y.r,x.i+y.i);}
        friend complex operator -(complex x,complex y){return complex(x.r-y.r,x.i-y.i);}
        friend complex operator *(complex x,complex y){return complex(x.r*y.r-x.i*y.i,x.r*y.i+x.i*y.r);}
    }A[410000],B[410000],C[410000]; int Re[410000];
    void fft(complex *a,int n,int op)
    {
        for(int i=0;i<n;i++)
            if(i<Re[i])swap(a[i],a[Re[i]]);
            
        for(int i=1;i<n;i<<=1)
        {
            complex wn(cos(pi/i),sin(op*pi/i));
            for(int j=0;j<n;j+=(i<<1))
            {
                complex w(1,0);
                for(int k=0;k<i;k++,w=w*wn)
                {
                    complex t1=a[j+k],t2=a[j+k+i]*w;
                    a[j+k]=t1+t2;a[j+k+i]=t1-t2;
                }
            }
        }
    }
    
    int len,n,aa[51000],bb[51000];
    LL solve(int CC)
    {
        memset(A,0,sizeof(A));
        memset(B,0,sizeof(B));
        LL sum=0;
        for(int i=0;i<len;i++)
        {
            A[i].r=A[len+i].r=aa[i]+CC, B[i].r=bb[len-1-i];
            sum+=sqr(aa[i]+CC)+sqr(bb[len-1-i]);
        }
        
        fft(A,n,1),fft(B,n,1);
        for(int i=0;i<n;i++)C[i]=A[i]*B[i];
        fft(C,n,-1);
        
        LL ret=(1LL<<62);
        for(int i=len-1;i<=2*(len-1);i++)
            ret=min(ret,sum-2*LL(C[i].r/n+0.5));
        return ret;
    }
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int M; LL sum=0;
        scanf("%d%d",&len,&M);
        for(int i=0;i<len;i++)scanf("%d",&aa[i]),sum+=aa[i];
        for(int i=0;i<len;i++)scanf("%d",&bb[i]),sum-=bb[i];
        sum/=len;
        
        int m=len*3,L=0;
        for(n=1;n<=m;n*=2)L++;
        for(int i=1;i<=n;i++)Re[i]=(Re[i>>1]>>1)|((i&1)<<(L-1));
        
        LL mmin=(1LL<<62);
        for(int C=sum-1;C<=sum+1;C++)
            mmin=min(mmin,solve(C));
        printf("%lld
    ",mmin);
        
        return 0;
    }

      

  • 相关阅读:
    opensuse使用zypper安装软件
    补习系列(1)-springboot项目基础搭建课
    补习系列-springboot-使用assembly进行项目打包
    log4j2 使用纪要
    mongos-sharding连接池配置
    maven-代码风格检查工具
    mtools-你可能没用过的mongodb神器
    mongodb分布式集群搭建手记
    mongodb分片扩展架构
    mongodb副本集高可用架构
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10153601.html
Copyright © 2011-2022 走看看