• BZOJ4827:[AH2017/HNOI2017]礼物——题解


    https://www.lydsy.com/JudgeOnline/problem.php?id=4827 

     https://www.luogu.org/problemnew/show/P3723

     题面见原题。

    参考了洛谷一些题解。

    先推式子,x数组为a,y数组为b,将b数组倍长后有:

    因为c的范围在[-m,m]之间,而m=100,且稍加思考后发现k在1,3,4项中是无用的,所以通过枚举c取得1,3,4项和的最小值。

    考虑计算第二项,其实是卷积型,实际上将a数组前移并倒转即可得到:

    变成了卷积,FFT即可O(nlogn),本题结束。

    (PS:防止我以后看不懂写点东西)

    (从n-1枚举到FFT的长度,在之间取得最大值即可)

    (至于为什么k可以被忽略,是因为当长度大于n-1时b[k]之前的项相当于乘了个0所以没事。)

    (当然我写的时候发现答案对了就交了结果就阴差阳错的AC了:) )

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cctype>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    using namespace std;
    typedef long double dl;
    typedef long long ll;
    const dl pi=acos(-1.0);
    const int N=2e6+5;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    struct complex{//定义复数 
        dl x,y;
        complex(dl xx=0.0,dl yy=0.0){
            x=xx;y=yy;
        }
        complex operator +(const complex &b)const{
            return complex(x+b.x,y+b.y);
        }
        complex operator -(const complex &b)const{
            return complex(x-b.x,y-b.y);
        }
        complex operator *(const complex &b)const{
            return complex(x*b.x-y*b.y,x*b.y+y*b.x);
        }
    };
    void FFT(complex a[],int n,int on){
        for(int i=1,j=n>>1;i<n-1;i++){
            if(i<j)swap(a[i],a[j]);
            int k=n>>1;
            while(j>=k){j-=k;k>>=1;}
            if(j<k)j+=k;
        }
        for(int i=2;i<=n;i<<=1){
            complex res(cos(-on*2*pi/i),sin(-on*2*pi/i));
            for(int j=0;j<n;j+=i){
                complex w(1,0);
                for(int k=j;k<j+i/2;k++){
                    complex u=a[k],t=w*a[k+i/2];
                    a[k]=u+t;
                    a[k+i/2]=u-t;
                    w=w*res;
                }
            }
        }
        if(on==-1)
            for(int i=0;i<n;i++)a[i].x/=n;
    }
    complex a[N],b[N];
    int n,m;
    ll t1=0,t2=0,t3=0,t4=0;
    inline ll suan(int c){
        return (ll)n*c*c+2*(t3-t4)*c;
    }
    int main(){
        n=read(),m=read();
        for(int i=n-1;i>=0;i--)a[i].x=read();
        for(int i=0;i<n;i++)b[i].x=read();
        for(int i=0;i<n;i++){
            t1+=a[i].x*a[i].x;t2+=b[i].x*b[i].x;
            t3+=a[i].x;t4+=b[i].x;
        }
        
        for(int i=n;i<2*n;i++)b[i]=b[i-n];
        int k=1;while(k<n*3)k<<=1;
        FFT(a,k,1);FFT(b,k,1);
        for(int i=0;i<k;i++)a[i]=a[i]*b[i];
        FFT(a,k,-1);
        
        ll maxn=0,minn=1e18;
        for(int i=n-1;i<k;i++)maxn=max(maxn,(ll)(a[i].x+0.5));
        for(int i=-m;i<=m;i++)
            if(suan(i)<minn)minn=suan(i);
        printf("%lld
    ",t1+t2-2*maxn+minn);
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

    +本文作者:luyouqi233。               +

    +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/ +

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    Bom入门
    Dom入门
    JavaScript对象
    Ultra-QuickSort——[归并排序、分治求逆序对]
    UVA 11212 Editing a Book [迭代加深搜索IDA*]
    Anagram——[枚举全排列]
    Black Box--[优先队列 、最大堆最小堆的应用]
    Argus--[优先队列]
    UVa1601
    UVa 10603 Fill [暴力枚举、路径搜索]
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/8998086.html
Copyright © 2020-2023  润新知