链接
http://www.lydsy.com/JudgeOnline/problem.php?id=4827
题解
裸的
FFT
,但是我调了一下午(虽然最后1A),我码力真的是弱爆了。
根据题意,可以直接写出式子
ans=∑i=1n(ai+d−bi+x)2
拆开搞一搞就行了
题外话
拆开之后,除了和
d
有关的哪些项的预处理都是
代码
//FFT
#include <cstdio>
#include <cmath>
#include <algorithm>
#define maxn (262144+10)
using namespace std;
int N, M, up, R[maxn], ans;
const double pi=acos(-1);
struct com
{
double x, y;
com(double x, double y):x(x),y(y){}
com(){};
}a[maxn], b[maxn], c[maxn];
inline com operator+(com a, com b){return com(a.x+b.x,a.y+b.y);}
inline com operator-(com a, com b){return com(a.x-b.x,a.y-b.y);}
inline com operator*(com a, com b){return com(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
inline void fft(com *a, int n, int opt)
{
int i, j, k; com wn, w, x, y;
for(i=0;i<n;i++)if(i>R[i])swap(a[i],a[R[i]]);
for(i=1;i<n;i<<=1)
{
wn=com(cos(pi/i),opt*sin(pi/i));
for(j=0;j<n;j+=i<<1)
for(w=com(1,0),k=0;k<i;k++,w=w*wn)
{
x=a[k+j], y=a[k+j+i]*w;
a[k+j]=x+y, a[k+j+i]=x-y;
}
}
if(opt==-1)for(i=0;i<n;i++)a[i].x/=n;
}
inline void juan(com *a, com *b, com *c)
{
fft(a,up,1), fft(b,up,1);
for(int i=0;i<up;i++)c[i]=a[i]*b[i];
fft(c,up,-1);
}
void init()
{
int i, L, d, sa=0, sb=0, t;
scanf("%d%d",&N,&M);
for(i=0;i<N;i++)scanf("%lf",&a[i].x),a[N+i].x=a[i].x;
for(i=0;i<N;i++)scanf("%lf",&b[i].x),b[N+i].x=b[i].x;
for(i=0;i<2*N-1-i;i++)swap(a[i],a[2*N-1-i]);
for(up=1,L=0;up<4*N;up<<=1)L++;
for(i=0;i<up;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
for(i=0;i<N;i++)ans+=a[i].x*a[i].x+b[i].x*b[i].x, sa+=a[i].x, sb+=b[i].x;
for(d=0,t=0x7fffffff;d<=M;d++)t=min(t,d*d*N+2*d*(sa-sb));
ans+=t;
}
int main()
{
int i; double x;
init();
juan(a,b,c);
for(x=-1e100,i=N-1;i<=2*N-2;i++)x=max(x,c[i].x-c[i-N].x);
ans-=int(x+0.5)*2;
printf("%d",ans);
return 0;
}