枚举对一个环整体加上的值c=-m~m,则答案
$\sum_{i=0}^{n-1}{(a_i-b_{(i+d)\%n}+c)^2}$
$=\sum_{i=0}^{n-1}{(a_i^2+b_i^2+c^2-2cb_i+2ca_i-2a_ib_{(i+d)\%n})}$
其中只有$\sum_{i=0}^{n-1}{a_ib_{(i+d)\%n}}$一项不能直接计算,但可以看出这是循环卷积的形式,用fft求出对每个d的答案,再取最大值即可
#include<cstdio> #include<cmath> #include<algorithm> #define G *++ptr char buf[2000000],*ptr=buf-1; int _(){ int x=0,c=G; while(c<48)c=G; while(c>47)x=x*10+c-48,c=G; return x; } const int M=133333; const double _2pi=acos(-1)*2; struct cplx{ double a,b; cplx(double _a=0,double _b=0):a(_a),b(_b){} cplx operator+(cplx x){return cplx(a+x.a,b+x.b);} cplx operator-(cplx x){return cplx(a-x.a,b-x.b);} cplx operator*(cplx x){return cplx(a*x.a-b*x.b,a*x.b+b*x.a);} }A[M],B[M],e[2][M]; int N,P; int n,m,r[M],a[50007],b[50007],a2=0,a1=0,b2=0,b1=0,ans=0x7fffffff,ab=0; void dft(cplx*a,int t){ for(int i=0;i<N;++i)if(i<r[i])std::swap(a[i],a[r[i]]); for(int i=1;i<N;i<<=1){ for(int j=0,z=N/(i<<1);j<N;j+=i<<1){ cplx*b=a+j,*c=b+i; for(int k=0;k<i;++k){ cplx x=b[k],y=c[k]*e[t][k*z]; b[k]=x+y; c[k]=x-y; } } } if(t)for(int i=0;i<N;++i)a[i].a/=N; } int main(){ fread(buf,1,sizeof(buf),stdin)[buf]=0; n=_();m=_(); for(int i=0;i<n;++i)a[i]=_(),a2+=a[i]*a[i],a1+=a[i]; for(int i=0;i<n;++i)b[i]=_(),b2+=b[i]*b[i],b1+=b[i]; for(N=2,P=0;N<n*2+3;N<<=1,++P); for(int i=1;i<N;++i)r[i]=r[i>>1]>>1|(i&1)<<P; for(int i=0;i<N;++i){ e[0][i]=cplx(cos(i*_2pi/N),sin(i*_2pi/N)); e[1][i]=cplx(cos(i*_2pi/N),-sin(i*_2pi/N)); } for(int i=0;i<n;++i)A[i]=a[n-1-i],B[i]=b[i]; dft(A,0);dft(B,0); for(int i=0;i<N;++i)A[i]=A[i]*B[i]; dft(A,1); for(int i=n;i<n*2;++i){ int v=int(A[i].a+A[i-n].a+0.49); if(v>ab)ab=v; } for(int c=-m;c<=m;++c){ int v=a2+b2+c*c*n-2*b1*c+2*a1*c-2*ab; if(v<ans)ans=v; } printf("%d\n",ans); return 0; }