zoukankan      html  css  js  c++  java
  • HNOI2017 礼物

    一道简单的(FFT)
    题目链接

    题意简述

    把一个数组全部加上一个整数(k),然后要使(sum_{i=1}^n(a_i-b_i)^2)最小.
    注意(a,b)这两个数组均可旋转.


    解析

    我们把式子展开.
    (sum_{i=1}^n(a_i-b_i+x)^2)
    (=sum_{i=1}^n(a_i^2+b_i^2+x^2+2a_ix-2b_ix-2a_ib_i))
    (=sum_{i=1}^n(a_i^2+b_i^2)+nx^2+2xsum_{i=1}^n(a_i-b_i)-sum_{i=1}^na_ib_i)
    考虑到(x)的取值范围很小,为((-100,100)),因此可以直接枚举.
    所以除了最后一项之外,其他的都知道了.
    考虑把(a)倍长,再把(b)反转.那么,乘积(c)的第(n+1,n+2...2n)就是答案.枚举一个(i)取个(min)即可.
    计算一下时间复杂度.
    (FFT)(O(n*log n))
    枚举是(O(n*m))的.
    因此总时间复杂度是(O(n*log n+n*m))的,可以通过此题.

    代码如下

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #define N (400010)
    #define inf (1e16)
    #define rg register int
    #define Label puts("NAIVE")
    #define spa print(' ')
    #define ent print('
    ')
    #define rand() (((rand())<<(15))^(rand()))
    typedef long double ld;
    typedef long long LL;
    typedef unsigned long long ull;
    using namespace std;
    inline char read(){
    	static const int IN_LEN=1000000;
    	static char buf[IN_LEN],*s,*t;
    	return (s==t?t=(s=buf)+fread(buf,1,IN_LEN,stdin),(s==t?-1:*s++):*s++);
    }
    template<class T>
    inline void read(T &x){
    	static bool iosig;
    	static char c;
    	for(iosig=false,c=read();!isdigit(c);c=read()){
    		if(c=='-')iosig=true;
    		if(c==-1)return;
    	}
    	for(x=0;isdigit(c);c=read())x=((x+(x<<2))<<1)+(c^'0');
    	if(iosig)x=-x;
    }
    inline char readchar(){
    	static char c;
    	for(c=read();!isalpha(c);c=read())
    	if(c==-1)return 0;
    	return c;
    }
    const int OUT_LEN = 10000000;
    char obuf[OUT_LEN],*ooh=obuf;
    inline void print(char c) {
    	if(ooh==obuf+OUT_LEN)fwrite(obuf,1,OUT_LEN,stdout),ooh=obuf;
    	*ooh++=c;
    }
    template<class T>
    inline void print(T x){
    	static int buf[30],cnt;
    	if(x==0)print('0');
    	else{
    		if(x<0)print('-'),x=-x;
    		for(cnt=0;x;x/=10)buf[++cnt]=x%10+48;
    		while(cnt)print((char)buf[cnt--]);
    	}
    }
    inline void flush(){fwrite(obuf,1,ooh-obuf,stdout);}
    const ld PI=3.14159265359;
    struct com{
    	ld a,b;
    	com(){a=b=0;}
    	com operator +(com x){
    		com res;
    		res.a=a+x.a,res.b=b+x.b;
    		return res;
    	}
    	com operator -(com x){
    		com res;
    		res.a=a-x.a,res.b=b-x.b;
    		return res;
    	}
    	com operator *(com x){
    		com res;
    		res.a=a*x.a-b*x.b,res.b=a*x.b+b*x.a;
    		return res;
    	}
    }a[N],b[N];
    int n,m,Lim,len,rev[N];
    LL a2,sa,b2,sb;
    void FFT(com *a,int tp){
    	for(int i=0;i<Lim;i++)
    	if(i<rev[i])swap(a[i],a[rev[i]]);
    	for(int i=1;i<Lim;i<<=1){
    		com w; w.a=cos(PI/i),w.b=tp*sin(PI/i);
    		for(int R=i<<1,j=0;j<Lim;j+=R){
    			com p; p.a=1;
    			for(int k=j;k<j+i;k++,p=p*w){
    				com x=a[k],y=p*a[k+i];
    				a[k]=x+y,a[k+i]=x-y;
    			}
    		}
    	}
    	if(tp==-1)
    	for(int i=0;i<Lim;i++)
    	a[i].a/=(ld)Lim;
    }
    int main(){
    	read(n),read(m);
    	for(int i=1;i<=n;i++){
    		int x; read(x);
    		a2+=(LL)x*x,sa+=x;
    		a[i].a=a[i+n].a=x;
    	}
    	for(int i=1;i<=n;i++){
    		int x; read(x);
    		b2+=(LL)x*x,sb+=x;
    		b[n-i+1].a=x;
    	}
    	for(Lim=1;Lim<=n*3;Lim<<=1)len++;
    	for(int i=0;i<Lim;i++)
    	rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1));
    	FFT(a,1),FFT(b,1);
    	for(int i=0;i<Lim;i++)a[i]=(a[i]*b[i]);
    	FFT(a,-1);
    	LL ans=inf;
    	for(int i=n+1;i<=2*n;i++)
    	for(int j=-m;j<=m;j++)
    	ans=min(ans,a2+b2+2ll*(LL)j*(sa-sb)+(LL)n*(LL)j*(LL)j-(LL)round(a[i].a)*2ll);
    	printf("%lld
    ",ans);
    }
    
  • 相关阅读:
    [转]ATOM 规范 中文版
    Silverlight 点滴(一) 获取定义在Generic.xaml或其他*.xaml中的对象
    [转]将WinCE5.0模拟器(emulator)连接到VS2005
    div+css布局实例淘宝分析(三)(2)
    介绍几款所见即所得的WEB在线编辑器
    cFos V7.52 简体中文破解版
    div+css布局实例淘宝分析(三)(1)
    div+css布局实例淘宝分析(一)
    中国水网开通了
    div+css布局实例淘宝分析(三)(3)
  • 原文地址:https://www.cnblogs.com/Romeolong/p/10075194.html
Copyright © 2011-2022 走看看