• bzoj 4827 礼物


    bzoj 4827 礼物

    • 可以看做将其中一个数列(假定为 (a) )都加上 (c) , (c) 可以为负数.易知这里 (-mleq cleq m).
    • 记要求的答案为 (ans) , 大力拆开括号可得:

    [ans=sum{(a_i+c-b_i)^2}\=sum a_i^2+sum b_i^2+ncdot c^2+2ccdot (sum a_i-sum b_i)-2sum a_i b_i. ]

    • 这里的 (a,b) 是原数列元素不变,通过旋转得到的.
    • 其中前两项是确定的,中间两项只与 (c) 有关,最后一项只与旋转方式有关.
    • (c) 的取值范围很小,可以枚举 (c) 求中间两项的最小值,而求最后一项的最大值,有一个做法:
    • (a) 翻转后重复一次,即拼接成 (a'=a^Ra^R),做卷积 (a''=a'otimes b), 则 (a'')(n+1)(2n) 的项恰好对应了通过每种旋转方式后的 (sum a_i b_i) ,可以通过验证得出.对这些项取一个最大值即可.
    • (FFT) 加速卷积过程,总时间复杂度为 (O(nlogn)) .
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define mp make_pair
    #define pii pair<int,int>
    #define max(a,b) ((a) < (b) ? b : a)
    #define min(a,b) ((a) < (b) ? a : b)
    inline int read()
    {
    	int x=0; 
    	bool pos=1; 
    	char ch=getchar();
    	for(;!isdigit(ch);ch=getchar())
    		if(ch=='-')
    			pos=0;
    	for(;isdigit(ch);ch=getchar())
    		x=x*10+ch-'0';
    	return pos?x:-x;
    }
    void write(int x)
    {
    	if(x>=10)
    		write(x/10);
    	putchar(x%10+'0');
    }
    void writeln(int x)
    {
    	write(x); 
    	puts("");
    }
    struct cp{
        double x,y;
        cp(double xx=0,double yy=0){x=xx;y=yy;}
        cp operator +(const cp &b){return cp(x+b.x,y+b.y);}
        cp operator -(const cp &b){return cp(x-b.x,y-b.y);}
        cp operator *(const cp &b){return cp(x*b.x-y*b.y,x*b.y+y*b.x);}
    };
    const double PI=acos(-1.0);
    const int MAXN=6e5+10;
    cp omega[MAXN],inv[MAXN];
    int rev[MAXN];
    void init(int n,int lim)
    {
    	for(int i=0; i<n; ++i)
    	{
    		for(int j=0; j<lim; ++j)
    			if((i>>j)&1)
    				rev[i]|=1<<(lim-j-1);
    	}
    }
    void FFT(cp *a,int n,bool invflag)
    {
    	for(int i=0; i<n; ++i)
    	{
    		if(i<rev[i])
    			swap(a[i],a[rev[i]]);
    	}
    	for(int l=2; l<=n; l<<=1)
    	{
    		int m=l>>1;
    		cp wi=cp(cos(2*PI/l),sin(2*PI/l));
    		if(invflag)
    			wi=cp(cos(2*PI/l),-sin(2*PI/l));
    		for(int p=0; p<n; p+=l)
    		{
    			cp w=cp(1,0);
    			for(int i=0; i<m; ++i)
    			{
    				cp t=w*a[i+m+p];
    				a[i+m+p]=a[i+p]-t;
    				a[i+p]=a[i+p]+t;
    				w=w*wi;
    			}
    		}
    	}
    	if(invflag)
    	{
    		for(int i=0; i<n; ++i)
    			a[i].x/=n,a[i].y/=n;
    	}
    }
    ll suma=0,sumb=0,sqa=0,sqb=0,sdif=0,mulmax=0;
    int n,m;
    cp a[MAXN],b[MAXN];
    int main()
    {
    	n=read(),m=read();
    	for(int i=0;i<n;++i)
    		{
    			int x=read();
    			a[i]=x;
    			suma+=x;
    			sqa+=x*x;
    		}
    	reverse(a,a+n);
    	for(int i=n;i<2*n;++i)
    		a[i]=a[i-n];
    	for(int i=0;i<n;++i)
    		{
    			int x=read();
    			b[i]=x;
    			sumb+=x;
    			sqb+=x*x;
    		}
    	sdif=suma-sumb;
    	int N=1,lim=0;
    	while(N<3*n)
    		N<<=1,++lim;
    	init(N,lim);
    	FFT(a,N,0);
    	FFT(b,N,0);
    	for(int i=0;i<N;++i)
    		a[i]=a[i]*b[i];
    	FFT(a,N,1);
    	for(int i=n;i<2*n;++i)
    		mulmax=max(mulmax,(long long)(a[i].x+0.5));
    	ll ans=1e18;
    	for(int c=-m;c<=m;++c)
    		ans=min(ans,sqa+sqb+n*c*c+2*c*sdif-2*mulmax);
    	printf("%lld
    ",ans);
    	return 0; 
    }
    
  • 相关阅读:
    harbor 报错,注意harbor.yml文件格式。
    nginx中rewrite文件
    改善github网络连接
    代码层实现六种质量属性战术
    读漫谈架构有感
    “淘宝网”的六个质量属性的六个常见属性
    寒假学习进度16:tensorflow2.0 波士顿房价预测
    寒假学习进度15:tensorflow2.0 优化器
    寒假学习进度14:对mnist数据集实现逻辑回归
    寒假学习进度13:tensorflow2.0 mnist简介
  • 原文地址:https://www.cnblogs.com/jklover/p/10388828.html
Copyright © 2020-2023  润新知