BZOJ 4827: [Hnoi2017]礼物 FFT_多项式_卷积
Code:
#include <bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin)
#define maxn 3100000
#define ll long long
using namespace std;
namespace FFT
{
#define pi 3.1415926535898
struct cpx
{
double x,y;
cpx(double a=0,double b=0){x=a,y=b;}
};
cpx operator+(cpx a,cpx b) { return cpx(a.x+b.x,a.y+b.y); }
cpx operator-(cpx a,cpx b) { return cpx(a.x-b.x,a.y-b.y); }
cpx operator*(cpx a,cpx b) { return cpx(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x); }
void FFT(cpx *a,int n,int flag)
{
for(int i = 0,k = 0;i < n; ++i)
{
if(i > k) swap(a[i],a[k]);
for(int j = n >> 1;(k^=j)<j;j>>=1);
}
for(int mid=1;mid<n;mid<<=1)
{
cpx wn(cos(pi/mid),flag*sin(pi/mid)),x,y;
for(int j=0;j<n;j+=(mid<<1))
{
cpx w(1,0);
for(int k=0;k<mid;++k)
{
x = a[j+k],y=w*a[j+mid+k];
a[j+k]=x+y;
a[j+mid+k]=x-y;
w=w*wn;
}
}
}
if(flag==-1) for(int i=0;i<n;++i) a[i].x/=(double)n;
}
cpx A[maxn],B[maxn];
void mult(int *a,int *b,int len)
{
int m = 1;
while(m <= len) m <<= 1;
for(int i = 0;i < len; ++i) A[i].x = (double)a[i];
for(int i = 0;i < len; ++i) B[i].x = (double)b[i];
FFT(A,m,1),FFT(B,m,1);
for(int i = 0;i < m; ++i) A[i] = A[i] * B[i]; // , printf("%.2f\n",A[i].x);
FFT(A,m,-1);
for(int i = 0;i < len; ++i) a[i] = (int)(A[i].x + 0.5);
}
};
int arr[maxn],brr[maxn],n,m,t;
ll ans = 0;
int main()
{
// setIO("input");
scanf("%d%d",&n,&m);
for(int i = 0;i < n; ++i) scanf("%d",&arr[i]);
for(int i = 0;i < n; ++i) scanf("%d",&brr[i]);
for(int i = 0;i < n; ++i)
{
ans += 1ll*arr[i]*arr[i] + 1ll*brr[i]*brr[i];
t += brr[i]-arr[i];
}
int c1 = floor(t*1.0/n), c2 = ceil(t*1.0/n);
ans += min(1ll*c1*c1*n - 1ll*c1*2*t, 1ll*c2*c2*n - 1ll*c2*2*t);
reverse(&arr[0],&arr[n]);
for(int i = n;i < 2*n;++i) brr[i]=brr[i-n];
FFT::mult(brr,arr,3*n);
int tmp = 0;
for(int i = 0;i < n; ++i) tmp = max(tmp,brr[i + n]) ;
ans -= (tmp<<1);
printf("%lld\n",ans);
return 0;
}