[HNOI2017]礼物


Description

我的室友最近喜欢上了一个可爱的小女生。马上就要到她的生日了,他决定买一对情侣手环,一个留给自己,一个送给她。每个手环上各有 n 个装饰物,并且每个装饰物都有一定的亮度。
但是在她生日的前一天,我的室友突然发现他好像拿错了一个手环,而且已经没时间去更换它了!他只能使用一种特殊的方法,将其中一个手环中所有装饰物的亮度增加一个相同的自然数 c(即非负整数)。并且由于这个手环是一个圆,可以以任意的角度旋转它,但是由于上面装饰物的方向是固定的,所以手环不能翻转。需要在经过亮度改造和旋转之后,使得两个手环的差异值最小。
在将两个手环旋转且装饰物对齐了之后,从对齐的某个位置开始逆时针方向对装饰物编号1,2,…,n,其中 n 为每个手环的装饰物个数, 第 1 个手环的 i 号位置装饰物亮度为 \(x_i\),第 2 个手环的 i 号位置装饰物亮度为 \(y_i\),两个手环之间的差异值为\(\sum_{i=1}^{n}(x_i-y_i)^2\)

麻烦你帮他计算一下,进行调整(亮度改造和旋转),使得两个手环之间的差异值最小,这个最小值是多少呢?

HINT

\(1\leq n\leq50000, 1\leq m\leq100, 1\leq a_i\leq m\).

Solution

\(\begin{split}&\sum(x_i+c-y_i)^2\\=&\sum(x_i^2+y_i^2)+[nc^2+2c\sum(x_i-y_i)]-2\sum x_iy_i\end{split}\)

关于c的二次函数可以直接枚举求最值.

再求个循环卷积就解决了.

#define N 50005
#define K 131073
typedef long double ld;
const ld pi=acos(-1.0);
struct cp{
	ld x,y;
	cp() {}
	cp(ld x,ld y):x(x),y(y) {}
	friend cp operator + (cp a,cp b){
		return cp(a.x+b.x,a.y+b.y);
	}
	friend cp operator - (cp a,cp b){
		return cp(a.x-b.x,a.y-b.y);
	}
	friend cp operator * (cp a,cp b){
		return cp(a.x*b.x-a.y*b.y,a.y*b.x+a.x*b.y);
	}
}a1[K],b1[K],a2[K],b2[K];
namespace FFT{
	int re[K],n;cp w[2][K];
	inline void init(int k){
		k<<=1;n=1;while(n>1;
			for(cp *p=a;p!=a+n;p+=l)
				for(int i=0;i

2017-04-22 08:44:13

FFT