[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