分析
显然两个手环增加非负整数亮度,等于其中一个增加一个整数亮度。
设亮度改变了 $c$,则新的差异值为
$$
\sum\limits_{i=1}^n(a_i-b_i+c)
$$
拆开得到
$$
\sum\limits_{i=1}^na_i^2+\sum\limits_{i=1}^nb_i^2+nc^2+2c\left[\sum\limits_{i=1}^n(a_i-b_i)\right]-2\sum\limits_{i=1}^na_ib_i
$$
前面两项是定值;带 $c$ 的两项是关于 $c$ 的二次函数,而且因为 $n>0$,所以有最小值,可以直接算出来;最后一项可以倍长 $a$ 并翻转,然后和 $b$ 卷积即可求出每个旋转角度的值,取个 $\max$ 即可。
代码
//It is made by M_sea
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define re register
typedef int mainint;
#define int long long
using namespace std;
inline int read() {
int X=0,w=1; char c=getchar();
while (c<'0'||c>'9') { if (c=='-') w=-1; c=getchar(); }
while (c>='0'&&c<='9') X=X*10+c-'0',c=getchar();
return X*w;
}
struct Complex {
double r,i;
Complex(double r_=0,double i_=0) { this->r=r_,this->i=i_; }
Complex operator +(const Complex& x) { return Complex(r+x.r,i+x.i); }
Complex operator -(const Complex& x) { return Complex(r-x.r,i-x.i); }
Complex operator *(const Complex& x) { return Complex(r*x.r-i*x.i,r*x.i+i*x.r); }
};
const int MAXN=400000+10;
const double PI=acos(-1.0);
int r[MAXN];
inline void FFT(Complex* a,int op,int n) {
for (re int i=0;i<n;++i)
if (i<r[i]) swap(a[i],a[r[i]]);
for (re int i=1;i<n;i<<=1) {
Complex rot(cos(PI/i),op*sin(PI/i));
for (re int j=0;j<n;j+=i<<1) {
Complex w(1,0);
for (re int k=0;k<i;++k,w=w*rot) {
Complex x=a[j+k],y=w*a[j+k+i];
a[j+k]=x+y,a[j+k+i]=x-y;
}
}
}
if (op==-1)
for (re int i=0;i<=n;++i) a[i].r/=n;
}
int n,m;
Complex f[MAXN],g[MAXN];
int a[MAXN],b[MAXN];
mainint main() {
n=read(),m=read();
int ans=0,delta=0;
for (re int i=1;i<=n;++i) a[i]=read(),ans+=a[i]*a[i],delta+=a[i];
for (re int i=1;i<=n;++i) b[i]=read(),ans+=b[i]*b[i],delta-=b[i];
int axis=(int)(round(-(double)delta/n)+0.5); //对称轴
int tmp=2147483647;
for (re int i=-1;i<=1;++i) { //check一下左右,不然会WA on #20
int now=axis+i;
tmp=min(tmp,n*now*now+2*now*delta);
}
ans+=tmp;
for (re int i=1;i<=n;++i) f[i].r=f[i+n].r=a[i];
for (re int i=1;i<=n;++i) g[i].r=b[n-i+1];
int len=1,l=0;
for (;len<=n*3;len<<=1,++l);
for (re int i=0;i<len;++i) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
FFT(f,1,len); FFT(g,1,len);
for (re int i=0;i<=len;++i) f[i]=f[i]*g[i];
FFT(f,-1,len);
int mx=-2147483647;
for (re int i=1;i<=n;++i) mx=max(mx,(int)(f[i+n].r+0.5));
printf("%lld\n",ans-2*mx);
return 0;
}
2 条评论
您好强啊qwq
您早就$\mathrm{A}$了,而且跑的还比我快%%%