就是求 ∑ni=1(ai−bi−z+x)2
(−m<=x<=m
,
z
为偏移量)
把式子打开,就是
发现是一个关于
x
的一元二次方程,系数只有最后的
看到两个多项式相乘很容易想到卷积。。那这个题就往上靠咯。
把
b
数组反一下,再在后面贴一段就好了。
就变成求
【代码】
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <complex>
#include <algorithm>
#include <cmath>
#define N 262145
#define INF 0x7fffffff
using namespace std;
typedef complex<double> C;
typedef long long ll;
const double pi=acos(-1);
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m,mm,K;
C a[N],b[N];
ll S,sum,mx,ans=1e18,AA;
void FFT(C *a,int n,int f)
{
if(n==1) return;
C wn(cos(2*pi/n),sin(2*pi*f/n)),w(1,0),t;
C a0[n>>1],a1[n>>1];
for(int i=0;i<n>>1;i++) a0[i]=a[i<<1],a1[i]=a[i<<1|1];
FFT(a0,n>>1,f),FFT(a1,n>>1,f);
for(int i=0;i<n>>1;i++,w*=wn)
{
t=w*a1[i];
a[i]=a0[i]+t;
a[i+(n>>1)]=a0[i]-t;
}
}
ll SQR(int x){
return 1LL*x*x;
}
ll FF(int x){
return (mm+1)*SQR(x)+sum*x+S;
}
int main()
{
n=m=mm=read()-1;K=read();
int tmp;
for(int i=0;i<=n;i++) a[i]=tmp=read(),S+=SQR(tmp),sum+=tmp<<1;
for(int i=n;i>=0;i--) b[i]=b[i+n+1]=tmp=read(),S+=SQR(tmp),sum-=tmp<<1;
m=m<<1|1;m+=n;
for(n=1;n<=m;n<<=1);
FFT(a,n,1);FFT(b,n,1);
for(int i=0;i<=n;i++) a[i]*=b[i];
FFT(a,n,-1);
for(int i=mm;i<=mm<<1;i++)
{
ll t=ll(a[i].real()/n+0.5);
mx=max(mx,t);
}
S-=mx<<1;
for(int i=-K;i<=K;i++)
ans=min(ans,FF(i));
printf("%lld\n",ans);
return 0;
}