首页 > 其他 > 详细

P3723 [AH2017/HNOI2017]礼物

时间:2019-01-19 23:16:07      阅读:195      评论:0      收藏:0      [点我收藏+]

题目

P3723 [AH2017/HNOI2017]礼物

做法

定义\(r\)为增加的亮度,其实我们可以定义\(r=-m\)~\(m\),简化成对一个环处理亮度

则我们要求最小值:
\[\begin{aligned} &\sum\limits_{i=1}^n(x_i+y_i+r)^2\&=\sum\limits_{i=1}^n(x_i^2+y_i^2-2x_iy_i-2y_ir+2x_ir+r^2)\&=(\sum\limits_{i=1}^nx_i^2+\sum\limits_{i=1}^ny_i^2)+(nr^2+2r(\sum\limits_{i=1}^na_i-\sum\limits_{i=1}^nb_i))-2\sum\limits_{i=1}^nx_iy_i \end{aligned}\]

其中左部分\(O(n)\),中间枚举\(O(m)\)

右部分\(\sum\limits_{i=1}^nx_iy_i\)\(x\)数组翻转一下,就成了卷积形式,然后再复制一倍,FFT后,\(A_{n+1}\)~\(A_{2n}\)就是不同的对接环形式,然后暴力枚举\(r\)

时间复杂度\(O(3nlog(3n)+nm)\)

My complete code

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
#include<ctime>
#include<cmath>
#include<vector>
using namespace std;
typedef int LL;
inline LL Read(){
    LL x(0),f(1);char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();
    return x*f;
}
const LL maxn=1e6,inf=0x3f3f3f3f;
const double Pi=acos(-1.0);
struct complex{
    double x,y;
    complex (double xx=0,double yy=0){x=xx,y=yy;}
}A[maxn],B[maxn];
LL n,m,a1,b1,a2,b2,limit,L,N,ans;
LL a[maxn],b[maxn],c[maxn],R[maxn];
complex operator -(complex x,complex y){
    return complex(x.x-y.x,x.y-y.y);
}
complex operator +(complex x,complex y){
    return complex(x.x+y.x,x.y+y.y);
}
complex operator *(complex x,complex y){
    return complex(x.x*y.x-x.y*y.y,x.x*y.y+x.y*y.x);
}
inline void FFT(complex *A,LL type){
    for(LL i=0;i<limit;++i)
        if(i<R[i])
            swap(A[i],A[R[i]]);
    for(int mid=1;mid<limit;mid<<=1){
        complex WN(cos(Pi/mid),type*sin(Pi/mid));
        for(int R=mid<<1,j=0;j<limit;j+=R){
            complex w(1,0);
            for(int k=0;k<mid;++k,w=w*WN){
                complex x=A[j+k],y=w*A[j+mid+k];
                A[j+k]=x+y,
                A[j+mid+k]=x-y;
            }
        }
    }
}
int main(){
    n=Read(),m=Read();
    for(LL i=1;i<=n;++i)
        a[i]=Read(),a1+=a[i]*a[i],a2+=a[i];
    for(LL i=1;i<=n;++i)
        b[i]=Read(),b1+=b[i]*b[i],b2+=b[i];
    for(LL i=1;i<=n;++i)
        c[i]=a[n-i+1],c[n+i]=c[i];
    N=3*n;
    limit=1,L=0;
    while(limit<N)
        limit<<=1,++L;
    for(LL i=0;i<limit;++i)
        A[i]=complex(1.0*c[i],0.0);
    for(LL i=0;i<limit;++i)
        B[i]=complex(1.0*b[i],0.0);
    for(LL i=0;i<limit;++i)
        R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
    FFT(A,1),FFT(B,1);
    for(LL i=0;i<limit;++i)
        A[i]=A[i]*B[i];
    FFT(A,-1); ans=inf;
    for(LL i=1;i<=n;++i)
        for(LL j=-m;j<=m;++j)
            ans=min(ans,a1+b1+(j*j*n+2*j*(a2-b2))-2*(LL)(A[i+n].x/limit+0.5));
    printf("%d\n",ans);
    return 0;
}

P3723 [AH2017/HNOI2017]礼物

原文:https://www.cnblogs.com/y2823774827y/p/10293604.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!