• 【[AH2017/HNOI2017]礼物】


    题目

    又是我不会做的题了

    看看柿子吧

    [sum(a_i+c-b_i)^2 ]

    最小化这个柿子

    之所以不写下标是因为我们这个({a},{b})可以循环同构

    那就开始化吧

    [sum(a_i+c-b_i)^2 ]

    [=sum(a_i+c)^2+sum b_i^2-sum2(a_i+c)b_i ]

    [=sum a_i^2+nc^2+csum 2a_i+sum b_i^2-csum b_i-2sum a_ib_i ]

    整理一下

    [sum a_i^2+sum b_i^2+nc^2+csum 2(a_i-b_i)-2sum a_ib_i ]

    前面的两项是定值,我们可以不用管

    中间的这个东西

    [nc^2+csum 2(a_i-b_i) ]

    这是一个关于(c)的二次函数,我们可以直接使得

    [c=-frac{sum 2(a_i-b_i)}{2n}=frac{sum b_i-a_i}{n} ]

    这样就能取得最小值了,但这样(c)可能不是整数,所以(c+1,c-1)都要试一下

    最后面这一项

    [2sum a_ib_i ]

    最大化这个就可以了

    这个东西跟循环同构可是有很大关系的

    我们发现我们可以将({a},{b})中的一个翻转以后被长,这样我们做就得到了一个卷积

    之后求出所有的(n)种来取一个(max)就好了

    代码

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define maxn 500005
    #define eps 1e-2
    #define re register
    #define LL long long
    #define double long double
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    inline int read()
    {
    	char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
    	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();
    	return x;
    }
    const double Pi=acos(-1);
    struct complex 
    {
    	double r,c;
    	complex (double a=0,double b=0) {r=a,c=b;}
    }f[maxn],g[maxn],og,og1,t;
    int n,a[maxn],b[maxn],m,len,rev[maxn];
    LL Sa,Sb,Sxa,Sxb;
    complex operator +(complex a,complex b) {return complex(a.r+b.r,a.c+b.c);}
    complex operator -(complex a,complex b) {return complex(a.r-b.r,a.c-b.c);}
    complex operator *(complex a,complex b) {return complex(a.r*b.r-a.c*b.c,a.r*b.c+a.c*b.r);}
    inline void FFT(complex *f,int v)
    {
    	for(re int i=0;i<=len;i++) if(i<rev[i]) std::swap(f[i],f[rev[i]]);
    	for(re int i=2;i<=len;i<<=1)
    	{
    		int ln=i>>1;
    		og1=complex(cos(Pi/ln),v*sin(Pi/ln));
    		for(re int l=0;l<len;l+=i)
    		{
    			og=complex(1,0);
    			for(re int x=l;x<l+ln;x++)
    			{
    				t=og*f[x+ln];
    				f[x+ln]=f[x]-t;
    				f[x]=f[x]+t;
    				og=og*og1;
    			}
    		}
    	}
    }
    int main()
    {
    	n=read();m=read();
    	for(re int i=1;i<=n;i++) a[i]=read(),Sa+=a[i],Sxa+=a[i]*a[i];
    	for(re int i=1;i<=n;i++) b[i]=read(),Sb+=b[i],Sxb+=b[i]*b[i];
    	len=1;while(len<n+n+n+3) len<<=1;
    	for(re int i=1;i<=n;i++) f[i].r=a[i],f[i].c=0;
    	for(re int i=1;i<=n;i++) g[i].r=b[n-i+1],g[i].c=0,g[i+n]=g[i];
    	for(re int i=0;i<=len;i++) rev[i]=(rev[i>>1]>>1)|((i&1)?(len>>1):0);
    	FFT(f,1),FFT(g,1);
    	for(re int i=0;i<len;i++) f[i]=f[i]*g[i];
    	FFT(f,-1);
    	for(re int i=0;i<len;i++) f[i].r/=len;
    	double now=0;
    	for(re int i=n+1;i<=n+n+1;i++) now=max(now,f[i].r);
    	LL ans=(now+eps);
    	ans=Sxa+Sxb-2*ans;
    	double mid=(Sb-Sa)/n;
    	LL X=mid; 
    	LL last=(LL)n*X*X+X*2*(Sa-Sb)+ans;
    	X++;last=min(last,(LL)n*X*X+X*2*(Sa-Sb)+ans);
    	X-=2;last=min(last,(LL)n*X*X+X*2*(Sa-Sb)+ans);
    	printf("%lld
    ",last);
    	return 0;
    }
    
  • 相关阅读:
    逆变电路技术研究!
    GOOGLE日历(管理自己的日常事务!)
    MATLAB使用的几个小问题(随笔记录下,用作以后参考!)
    ASP.NET截取字符串
    ASP.NET以及JS获取URL和IP地址
    Jvascript 做IE功能按钮,打开、另存为。属性、打印、收藏夹等js按钮
    C# winform 动态添加控件 以及 事件
    VS2008简体中文正式版序列号
    js 获取日期
    ASP.NET读取XML某节点所有数据返回DataTable实例
  • 原文地址:https://www.cnblogs.com/asuldb/p/10278293.html
Copyright © 2020-2023  润新知