#3178. 礼物(gift)

题目描述
题解

假设亮度加 c ( c ∈ [ − m , m ] ) c(c \in [-m,m]) c(c[m,m]) ,将 b b b 数组延长两倍,假设 b b b 数组从第 k k k 个位置开始匹配,那我们要求的就是 min ⁡ k = 0 n − 1 { ∑ i = 0 n − 1 ( a i − b k + i + c ) 2 } \min_{k=0}^{n-1}\{\sum_{i=0}^{n-1}(a_i-b_{k+i}+c)^2\} k=0minn1{i=0n1(aibk+i+c)2}
把式子拆开,得到 ∑ i = 0 n − 1 a i 2 + b i 2 + 2 × c × ( a i − b i ) + c 2 − ∑ i = 0 n − 1 2 × a i × b k + i \sum_{i=0}^{n-1} a_i^2+b_i^2+2 \times c \times (a_i-b_i)+c^2-\sum_{i=0}^{n-1}2 \times a_i \times b_{k+i} i=0n1ai2+bi2+2×c×(aibi)+c2i=0n12×ai×bk+i
于是我们的目的是后面的式子尽量大,发现它们下标差是定值,于是把 a a a 数组翻转后 f f t fft fft 即可

效率: O ( n l o g n ) O(nlogn) O(nlogn)

代码
#include <bits/stdc++.h>
#define db double
using namespace std;
const int N=3e5+5;
const db PI=acos(-1);
int n,m,a[N],b[N],s,S,U,V,t=1,p,r[N];
struct O{db r,i;}A[N],B[N];
O operator + (O A,O B){
	return (O){A.r+B.r,A.i+B.i};
}
O operator - (O A,O B){
	return (O){A.r-B.r,A.i-B.i};
}
O operator * (O A,O B){
	return (O){A.r*B.r-A.i*B.i,A.r*B.i+A.i*B.r};
}
void FFt(O *a,int o){
	for (int i=0;i<t;i++)
		if (i<r[i]) swap(a[i],a[r[i]]);
	for (int i=1;i<t;i<<=1){
		O wn=(O){cos(PI/i),sin(PI/i)*o};
		for (int j=0;j<t;j+=(i<<1)){
			O w=(O){1,0},x,y;
			for (int k=0;k<i;k++,w=wn*w)
				x=a[j+k],y=a[i+j+k]*w,
				a[j+k]=x+y,a[i+j+k]=x-y;
		}
	}
	if (!~o) for (int i=0;i<t;i++) a[i].r/=t;
}
int main(){
	scanf("%d%d",&n,&m);
	for (int i=0;i<n;i++)
		scanf("%d",&a[i]),U+=a[i],
		A[n-i-1].r=a[i],S+=a[i]*a[i];
	for (int i=0;i<n;i++)
		scanf("%d",&b[i]),V+=b[i],
		B[i].r=B[i+n].r=b[i],S+=b[i]*b[i];
	for (;t<n*3;t<<=1,p++);
	for (int i=0;i<t;i++)
		r[i]=(r[i>>1]>>1)|((i&1)<<(p-1));
	FFt(A,1);FFt(B,1);
	for (int i=0;i<t;i++)
		A[i]=A[i]*B[i];FFt(A,-1);
	for (int i=n-1;i<n+n;i++)
		s=max(s,(int)(A[i].r+.5));
	S-=2*s;s=1e9;
	for (int i=-m;i<=m;i++)
		s=min(s,S+2*i*(U-V)+i*i*n);
	cout<<s<<endl;return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值