# 【Hnoi2017】礼物

### 数据范围

100%的数据保证$1≤n≤50000,1≤m≤100,1≤ai≤m$

$=\sum_{i=1}^{n}(x_i^2-y_{i+x}^2-2x_iy_{i+x}+2yx_i-2yy_i+y^2)$
$=\sum_{i=1}^{n}(x_i^2-y_{i}^2)-2*\sum_{i=1}^{n}x_iy_{i+x}+2y*\sum_{i=1}^{n}(x_i-y_i)+y^2$

$x'_i=x_{n-i+1}$，那么$2*\sum_{i=1}^{n}x_iy_{i+x}=2*\sum_{i=1}^{n}x'_{n-i+1}y_{i+x}$，这样就可以用FFT算出来了

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<climits>
#include<vector>
#include<cmath>
#include<map>
#include<set>
#include<complex>
#define LL long long

using namespace std;

inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}

char c=nc();int b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}

char c=nc();LL b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}

{
char c=nc();int len=0;
for(;!(c>='A' && c<='Z');c=nc()) if (c==EOF) return 0;
for(;(c>='A' && c<='Z');s[len++]=c,c=nc());
s[len++]='\0';
return len;
}

for (x=nc();!(x>='A' && x<='Z');x=nc());
}

int wt,ss[19];
inline void print(int x){
if (x<0) x=-x,putchar('-');
if (!x) putchar(48); else {
for (wt=0;x;ss[++wt]=x%10,x/=10);
for (;wt;putchar(ss[wt]+48),wt--);}
}
inline void print(LL x){
if (x<0) x=-x,putchar('-');
if (!x) putchar(48); else {for (wt=0;x;ss[++wt]=x%10,x/=10);for (;wt;putchar(ss[wt]+48),wt--);}
}

#define pi acos(-1)
#define E complex<double>
E a[500010],b[500010];
int n,m,x,f[50010],u[50010],v[50010];

void fft(E *x,int n,int tp)
{
if (n==1) return;
E l[n>>1],r[n>>1];
for (int i=0;i<n;i+=2)
l[i>>1]=x[i],r[i>>1]=x[i+1];
fft(l,n>>1,tp),fft(r,n>>1,tp);
E w(1,0),wn(cos(pi*2/n),sin(pi*2/n*tp)),t;
for (int i=0;i<n>>1;i++,w*=wn)
t=r[i]*w,x[i]=l[i]+t,x[i+(n>>1)]=l[i]-t;
}

int main()
{
int x,N=n;
for (int i=0;i<n;i++)
for (int i=0;i<n;i++)
for (int i=0;i<n;i++)
b[i+n]=b[i];
m=n*4;
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);
int Max=0;
for (int i=0;i<N;i++)
Max=max(Max,(int)(a[N+i-1].real()/n+0.5));
int ans=0;
for (int i=0;i<N;i++)
ans+=u[i]*u[i]+v[i]*v[i];
ans=ans-Max*2;
x=N;int y=0;
for (int i=0;i<N;i++)
y+=u[i]-v[i];
y=y*2;
int z=(-y)/(2*x);
Max=z*z*x+y*z;
z+=1,Max=min(Max,z*z*x+y*z);
z-=2,Max=min(Max,z*z*x+y*z);
ans+=Max;
print(ans),puts("");
return 0;
}
posted @ 2017-04-26 12:03  Xiejiadong  阅读(...)  评论(...编辑  收藏
levels of contents