「BZOJ3527」[Zjoi2014]力

把式子化简后发现是几个卷积形式

 1 #include<bits/stdc++.h>
 2 #define db double
 3 using namespace std;
 4 const int N=400000;
 5 const db PI=acos(-1);
 6 struct Complex{
 7     db real,image;
 8     Complex(db _real=0,db _image=0):real(_real),image(_image){}
 9     Complex operator+(Complex k){return Complex(real+k.real,image+k.image);}
10     Complex operator-(Complex k){return Complex(real-k.real,image-k.image);}
11     Complex operator*(Complex k){return Complex(real*k.real-image*k.image,real*k.image+image*k.real);}
12     Complex operator/(int k){return Complex(real/k,image/k);}
13 }a[N],b[N],c[N];
14 int on,n,m,maxp,rev[N];
15 void fft(Complex* x,int iff){
16     for(int i=0;i<n;i++) if(rev[i]>i) swap(x[i],x[rev[i]]);
17     for(int len=1;len<=n;len<<=1){
18         Complex wn(cos(2*PI/len),iff*sin(2*PI/len));
19         for(int now=0;now<n-1;now+=len){
20             Complex w(1,0);
21             for(int i=0;i<(len>>1);i++,w=w*wn){
22                 Complex t1=x[now+i],t2=w*x[now+(len>>1)+i];
23                 x[now+i]=t1+t2,x[now+(len>>1)+i]=t1-t2;
24             }
25         }
26     }
27     if(iff==-1) for(int i=0;i<n;i++) x[i]=x[i]/n;
28     return;
29 }
30 int main(){
31     db ans;
32     scanf("%d",&on),on--;
33     for(int i=0;i<=on;i++){
34         if(i) c[i].real=1.0/i/i;
35         scanf("%lf",&a[i].real),b[on-i].real=a[i].real;
36     }
37     m=on<<1;
38     for(n=1;n<=m;n<<=1) maxp++;
39     for(int i=1;i<n;i++) rev[i]=(rev[i>>1]>>1)|(i&1)<<(maxp-1);
40     fft(a,1);fft(b,1);fft(c,1);
41     for(int i=0;i<n;i++) a[i]=a[i]*c[i],b[i]=b[i]*c[i];
42     fft(a,-1);fft(b,-1);
43     for(int i=0;i<=on;i++){
44         ans=a[i].real-b[on-i].real;
45         printf("%lf
",ans);
46     }
47     return 0;
48 }
原文地址:https://www.cnblogs.com/mycups/p/8527826.html