zoukankan      html  css  js  c++  java
  • LG 3723 [AH2017/HNOI2017]礼物

    LG 3723 [AH2017/HNOI2017]礼物

    前言

    感觉这道 FFT 挺水的(((

    我这种蒟蒻都能做出来,一遍写对。估计这个题是真的有点简单了

    解法

    我们其实很快可以观察出一个性质:

    性质1

    对于增加的亮度 \(c\),可以小于 \(0\)

    这个太好理解了吧,就是不增加这一串的亮度,去增加另一串,不就相当于减小这一串的亮度吗?(挺绕的qwq)

    性质2

    对于增加的亮度 \(c\),一定满足 \(-m\leq c\leq m\)

    自证不难。

    这个也很容易证明。我们可以想,如果 \(|c|>m\),由于 \(\forall i\ \ a_i\leq m,b_i\leq m\),那么此时 \(c\) 一定不是最优的。

    我们开始推柿子。

    性质1,我们知道:

    \[ans=\min\limits_{x=-m}^m \sum\limits_{i=1}^n(a_i-b_i+x)^2 \]

    展开得:

    \[ans=\min\limits_{x=-m}^m \sum\limits_{i=1}^n({a_i}^2+{b_i}^2-2\cdot a_i\cdot b_i+2\cdot a_i\cdot x-2\cdot x\cdot b_i+x^2) \]

    略加整理得:

    \[ans=\min\limits_{x=-m}^m \sum\limits_{i=1}^n({a_i}^2+{b_i}^2)+2\cdot x\cdot\sum\limits_{i=1}^n (a_i-b_i)+n\cdot x^2+2\cdot\sum\limits_{i=1}^n a_i\cdot b_i \]

    如果我们枚举 \(x\),那么就只有 \(2\cdot\sum\limits_{i=1}^n a_i\cdot b_i\) 这一项是变量了,我们应该使这个部分的值最大。

    这不就是经典的翻转数组 FFT 吗?我们翻转数组 \(a\),这样这个部分就变为了 \(2\cdot\sum\limits_{i=1}^n a_{n-i+1}\cdot b_i\)。用 FFT 求两个多项式的积,然后看多项式 \(n+1\)\(2\cdot n\) 次项的系数,取最大值即可。最后在 \(-m\)\(m\) 的区间里枚举 \(x\) 即可。时间复杂度 \(O(n\log n+n+2\cdot m)\)

    如果你想优化亿点点时间复杂度,你可以用三分法去锁定 \(x\),把时间复杂度最后一项降低。

    或者你可以利用二次函数的性质,把式子想象成一个关于 \(x\) 的二次函数,利用对称轴求最值即可。

    但是你没必要在简单问题上耍杂技。除非在女同学面前qwq

    代码

    //Don't act like a loser.
    //This code is written by huayucaiji
    //You can only use the code for studying or finding mistakes
    //Or,you'll be punished by Sakyamuni!!!
    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    
    int read() {
    	char ch=getchar();
    	int f=1,x=0;
    	while(ch<'0'||ch>'9') {
    		if(ch=='-')
    			f=-1;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9') {
    		x=x*10+ch-'0';
    		ch=getchar();
    	}
    	return f*x;
    }
    
    const int MAXN=1e6+10;
    const double pi=acos(-1.0);
    typedef complex<double> Complex;
    
    int n,m,d,cost,coft;//constant,coefficient
    int a[MAXN],b[MAXN],r[MAXN];
    Complex f[MAXN],g[MAXN];
    
    void FFT(Complex A[],int inv) {
    	for(int i=0;i<d;i++) {
    		if(i<r[i]) {
    			swap(A[i],A[r[i]]);
    		}
    	}
    	
    	for(int len=1;len<d;len<<=1) {
    		Complex wn=Complex(cos(pi/len),inv*sin(pi/len));
    		for(int i=0;i<d;i+=len*2) {
    			Complex w(1,0);
    			for(int k=0;k<len;k++,w*=wn) {
    				Complex x=A[i+k];
    				Complex y=w*A[i+k+len];
    				A[i+k]=x+y;
    				A[i+k+len]=x-y;
    			}
    		}
    	}
    	
    	if(inv==-1) {
    		for(int i=0;i<d;i++) {
    			A[i]/=d;
    		}
    	}
    }
    
    signed main() {
    	cin>>n>>m;
    	for(int i=0;i<n;i++) {
    		a[i]=read();
    		cost+=a[i]*a[i];
    		f[i]=a[i];
    	}
    	for(int i=0;i<n;i++) {
    		b[i]=read();
    		cost+=b[i]*b[i];
    		coft+=a[i]-b[i];
    		g[i]=b[i];
    	}
    	reverse(f,f+n);
    	for(int i=n;i<2*n;i++) {
    		f[i]=f[i-n];
    	}
    	
    	d=1;
    	int l=0;
    	while(d<3*n) {
    		d<<=1;
    		l++;
    	}
    	for(int i=0;i<d;i++) {
    		r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    	}
    	
    	FFT(f,1);
    	FFT(g,1);
    	for(int i=0;i<d;i++) {
    		f[i]=f[i]*g[i];
    	}
    	FFT(f,-1);
    	
    	int maxx=-1;
    	for(int i=n;i<n*2;i++) {
    		maxx=max(maxx,(int)(f[i].real()+0.49)*2);
    	}
    	int ans=1e18;
    	cost-=maxx;
    	
    	for(int x=-m;x<=m;x++) {
    		ans=min(ans,cost+n*x*x+2*x*coft);
    	}
    	
    	cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    HttpServletRequest和HttpServletResponse
    .NET Core 通过 Ef Core 操作 Mysql
    spring-boot整合shiro实现权限管理
    spring-boot整合mongodb多数据源的案例
    spring-boot整合mybaits多数据源动态切换案例
    spring-boot整合Mybatis多数据源案例
    spring-boot整合mongodb的案例
    spring-boot和redis的缓存使用
    spring-boot 定时任务案例
    spring-cloud:熔断监控Hystrix Dashboard和Turbine的示例
  • 原文地址:https://www.cnblogs.com/huayucaiji/p/LG3723.html
Copyright © 2011-2022 走看看