傳送門php
發現題目中的式子貌似是讓在求
\[\sum_{i=1}^{n}(x_i-y_{i+k}+C)^2\]
能夠大力展開這個式子。
而後發現有關於\(C\)的項均可以\(O(1)\)求,二次項也能夠\(O(1)\),就只剩下一個\(-2\sum_{i=1}^{n}x_iy_{i+k}\)不是很好。c++
固然能夠\(n^2\)枚舉,而後問\(gay哥\)爲啥見着這種式子就能夠往FFT上想。spa
考慮卷積的通常形式是\(f(n)=\sum_{i=0}^{n}f(n-i)·g(i)\),因此能夠把前面的那一項反過來,而後破環成鏈倍長,以後n+1~n+n項中的最大值就是咱們要求的最大值。code
#include <bits/stdc++.h> using namespace std; const int MAXN=4e5+7; const double pi=acos(-1); const int inf=1e9+7; inline int read() { int x=0,c=1; char ch=' '; while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); while(ch=='-')c*=-1,ch=getchar(); while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); return x*c; } struct Complex{ double x,y; Complex (double xx=0,double yy=0){x=xx,y=yy;} friend Complex operator +(Complex a,Complex b){ return Complex(a.x+b.x,a.y+b.y); } friend Complex operator -(Complex a,Complex b){ return Complex(a.x-b.x,a.y-b.y); } friend Complex operator *(Complex a,Complex b){ return Complex((a.x*b.x)-(a.y*b.y),(a.x*b.y)+(a.y*b.x)); } }a[MAXN],b[MAXN]; int n,m,len,r[MAXN],N,l,s1[MAXN],s2[MAXN],s[MAXN],mx=-inf,ans=inf; inline void FFT(Complex *A,int type) { for(int i=0;i<N;i++) if(i<r[i]) swap(A[i],A[r[i]]); for(int mid=1;mid<N;mid<<=1){ Complex wn(cos(pi/mid),type*sin(pi/mid)); for(int R=mid<<1,j=0;j<N;j+=R){ Complex w(1,0); for(int k=0;k<mid;k++,w=w*wn){ Complex x=A[j+k],y=w*A[j+mid+k]; A[j+k]=x+y;A[j+k+mid]=x-y; } } } } inline void init() { n=read(),m=read(); for(int i=1;i<=n;i++) s1[i]=read(); for(int i=1;i<=n;i++) s2[i]=read(); N=n-1;len=n+n-1; for(int i=0;i<=N;i++) a[i].x=s1[i+1]; for(int i=0;i<n;i++) b[i].x=b[i+n].x=s2[n-i]; len+=N; } int main() { init(); N=1; while(N<=len) N<<=1,l++; for(int i=0;i<N;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1)); FFT(a,1);FFT(b,1); for(int i=0;i<N;i++) a[i]=a[i]*b[i]; FFT(a,-1); for(int i=0;i<=len;i++) s[i]=(int)(a[i].x/N+0.5); int p1=0,p2=0,t1=0,t2=0; for(int i=1;i<=n;i++) p1+=s1[i]*s1[i],p2+=s2[i]*s2[i],t1+=s1[i],t2+=s2[i]; for(int i=1;i<n+n;i++) mx=max(mx,s[i]); for(int C=-m;C<=m;C++){ int sum=p1+p2+n*C*C+2*C*t1-2*C*t2-2*mx; ans=min(sum,ans); } printf("%d",ans); }