BZOJ-4827-FFT
阿新 • • 發佈:2018-12-09
先不考慮+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; }