先不考虑+c,那么只需要把原式展开,将a数组扩大一倍,求fft即可。
#include<bits/stdc++.h>
#define N 262144
#define pi acos(-1)
#define ll long long
using namespace std;
typedef complex<double> E;
int n,m,L;
int rev[N];
E f[N],_f[N],e[N];
void fft(E *a,int f)
{
for(int i=0;i<n;i++)if(i>rev[i])swap(a[i],a[rev[i]]);
for(int i=1;i<n;i<<=1)
{
E wn(cos(pi/i),f*sin(pi/i));
for(int j=0;j<n;j+=(i<<1))
{
E w(1,0);
for(int k=0;k<i;k++,w*=wn)
{
E x=a[j+k],y=w*a[j+k+i];
a[j+k]=x+y;a[j+k+i]=x-y;
}
}
}
if(f==-1)for(int i=0;i<n;i++)a[i]/=n;
}
int t,a[N],b[N],c[N];
int pow(int x)
{
return x*x;
}
int main()
{
scanf("%d%d",&n,&t);
int nn =n;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
f[i]=a[i];
}
for(int i=n;i<2*n;i++)
f[i]=f[i-n];
int sum = 0, p =0;
for(int i=0;i<n;i++)
{
scanf("%d",&b[i]);
sum+=b[i];
p += pow(b[i]);
_f[n-1-i] = b[i];
}
m=2*n;
for(n=1;n<=m;n<<=1)L++;
for(int i=0;i<n;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));
fft(f,1);fft(_f,1);
for(int i=0;i<n;i++) e[i] = f[i]*_f[i];
fft(e,-1);
//
for(int i=0;i<2*nn;i++)
{
c[i] = (int)(e[i].real()+0.5);
//printf("%d\n",c[i]);
}
int ans = 0x7fffffff;
for(int k=-t;k<=t;k++)
{
int x = p;
for(int i=0;i<nn;i++)
x += pow(a[i]+k);
for(int i=nn;i<2*nn;i++)
{
int xx = x - 2*(c[i]+sum*k);
ans = min(ans,xx);
}
}
printf("%d\n",ans);
return 0;
}