BZOJ3527 ZJOI2014 力
阿新 • • 發佈:2018-12-10
傳送門
FFT復健中。。。
把柿子拆開 兩邊分別變成q卷g g是1/i^2就可以了(第二個把q翻轉就好了)
菜到這個都想不出(
附程式碼。
FFT學習筆記先等我鴿著吧
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<complex> #define inf 20021225 #define ll long long #define mxn 300100 #define db double #define eps 1e-8 using namespace std; int rev[mxn],l,lim,n; typedef complex<double> cp; cp a[mxn<<1],b[mxn<<1],q[mxn],p[mxn],g[mxn]; db ans[mxn]; const db PI=acos(-1); void FFT(cp *A,int f) { for(int i=0;i<lim;i++) if(rev[i]>i) swap(A[rev[i]],A[i]); for(int k=1;k<lim;k<<=1) { cp Wn=cp(cos(PI/k),f*sin(PI/k)); for(int R=k<<1,i=0;i<lim;i+=R) { cp w=1.0; for(int j=0;j<k;j++,w=w*Wn) { cp x=A[i+j],y=w*A[i+k+j]; A[i+j]=x+y; A[i+k+j]=x-y; } } } if(f==-1) for(int i=0;i<lim;i++) A[i]/=lim; } int main() { scanf("%d",&n);db x; for(int i=0;i<n;i++) scanf("%lf",&x),q[i]=x,p[n-i-1]=x; l=0;lim=1; while(lim<(n<<1)) lim<<=1,l++; for(int i=1;i<lim;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1)); for(int i=1;i<n;i++) g[i]=1.0/i/i; FFT(q,1);FFT(p,1);FFT(g,1); for(int i=0;i<lim;i++) a[i]=q[i]*g[i]; for(int i=0;i<lim;i++) b[i]=p[i]*g[i]; FFT(a,-1);FFT(b,-1); for(int i=0;i<n;i++) printf("%.8lf\n",a[i].real()-b[n-i-1].real()); return 0; }