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

    传送门

    没想到湖南省选也出板子题啊

    先把题目要求的式子拆一下

    [sum_{i=1}^{n}(a_i+x-b_i)^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)-2sum_{i=1}^{n}a_ib_i ]

    容易发现只有最后的(2sum_{i=1}^{n}a_ib_i)不是定值,其余的全都可以预先处理出来

    考虑将(a)数组reverse一下

    式子就成了这样

    [2sum_{i=1}^{n}a_{n-i+1}b_i ]

    再倍长一下(应该不用解释吧),然后就可以用fft求解了,最后就查询(n+1)(2n)内的最大值就好了

    讲一下一个细节:对于(nx^2+2xsum_{i=1}^{n}(a_i-b_i))用二次函数求解时,注意当(x)取负数时,取整应该是减去(0.5)(x)取正是加上(0.5)(原因不用多说,四舍五入之后是最靠近真实值的)

    代码:

    	#include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    void read(int &x) {
        char ch; bool ok;
        for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
        for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
    }
    #define rg register
    const int maxn=4e5+10;const double pi=acos(-1);
    struct complex{double x,y;}a[maxn*2],b[maxn];
    int n,m,nn,ans,sum,w,len,r[maxn];double tot;
    complex operator-(complex a,complex b){return (complex){a.x-b.x,a.y-b.y};}
    complex operator+(complex a,complex b){return (complex){a.x+b.x,a.y+b.y};}
    complex operator*(complex a,complex b){return (complex){a.x*b.x-a.y*b.y,a.y*b.x+b.y*a.x};}
    void fft(complex *a,int f)
    {
    	for(rg int i=0;i<n;i++)if(r[i]>i)swap(a[r[i]],a[i]);
    	for(rg int i=1;i<n;i<<=1)
    	{
    		complex wn=(complex){cos(pi/i),f*sin(pi/i)};
    		for(rg int j=0;j<n;j+=(i<<1))
    		{
    			complex w=(complex){1,0};
    			for(rg int k=0;k<i;k++)
    			{
    				complex x=a[j+k],y=w*a[j+k+i];
    				a[j+k]=x+y,a[j+k+i]=x-y,w=w*wn;
    			}
    		}
    	}
    	if(f==-1)for(rg int i=0;i<=m;i++)a[i].x=a[i].x/n+0.5; 
    }
    int main()
    {
    	read(n),read(m),nn=n;
    	for(rg int i=0,x;i<n;i++)read(x),a[i].x=x,sum+=x*x,tot+=x;
    	for(rg int i=0,x;i<n;i++)read(x),b[i].x=x,sum+=x*x,tot-=x;
    	for(rg int i=0;i<n>>1;i++)swap(a[i],a[n-i-1]);
    	for(rg int i=0;i<n;i++)a[i+n]=a[i];
    	w=(int)((-tot/n)<0?(-tot/n)-0.5:(-tot/n)+0.5);sum+=n*w*w+tot*2*w;
    	n<<=1;m=n+nn;for(n=1;n<=m;n<<=1)len++;
    	for(rg int i=0;i<n;i++)r[i]=(r[i>>1]>>1)|((i&1)<<(len-1));
    	fft(a,1),fft(b,1);
    	for(rg int i=0;i<n;i++)a[i]=a[i]*b[i];
    	fft(a,-1);ans=-1e9;
    	for(rg int i=0;i<nn;i++)ans=max(ans,(int)(a[i+nn].x));
    	printf("%d
    ",sum-ans*2);
    }
    
  • 相关阅读:
    tomcat的安装及配置
    java动态代理的实现
    mySql单列索引与联合索引的区别
    maven3.5.0在win10中的安装及环境变量配置
    jQuery相关知识总结
    前端-css
    前段篇:HTML
    Mysql基础安装,初视篇
    论事件驱动与异步IO
    python 之协程
  • 原文地址:https://www.cnblogs.com/lcxer/p/10624775.html
Copyright © 2011-2022 走看看