1. 程式人生 > >2018.11.18 bzoj2194: 快速傅立葉之二(fft)

2018.11.18 bzoj2194: 快速傅立葉之二(fft)

傳送門
模板題。
b b 序列反過來然後上 f f t fft 搞定。
程式碼:

#include
<bits/stdc++.h>
#define ri register int using namespace std; inline int read(){ int ans=0; char ch=getchar(); while(!isdigit(ch))ch=getchar(); while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar(); return ans; } const int N=4e5+5; const double pi=acos(-1.0); struct Complex{
double x,y; inline Complex operator+(const Complex&b){return (Complex){x+b.x,y+b.y};} inline Complex operator-(const Complex&b){return (Complex){x-b.x,y-b.y};} inline Complex operator*(const Complex&b){return (Complex){x*b.x-y*b.y,x*b.y+y*b.x};} inline Complex operator/(const double
&b){return (Complex){x/b,y/b};} }a[N],b[N]; int n,pos[N],lim,tim; inline void init(){ lim=1,tim=0; while(lim<=n*2)lim<<=1,++tim; for(ri i=0;i<lim;++i)pos[i]=(pos[i>>1]>>1)|((i&1)<<(tim-1)); } inline void fft(Complex *a,int type){ for(ri i=0;i<lim;++i)if(i<pos[i])swap(a[i],a[pos[i]]); for(ri mid=1;mid<lim;mid<<=1){ Complex wn=(Complex){cos(pi/mid),type*sin(pi/mid)}; for(ri j=0,len=mid<<1;j<lim;j+=len){ Complex w=(Complex){1,0}; for(ri k=0;k<mid;++k,w=w*wn){ Complex a0=a[j+k],a1=w*a[j+k+mid]; a[j+k]=a0+a1,a[j+k+mid]=a0-a1; } } } if(type==-1)for(ri i=0;i<lim;++i)a[i]=a[i]/lim; } int main(){ freopen("lx.in","r",stdin); n=read()-1,init(); for(ri i=0;i<=n;++i)a[i].x=read(),b[n-i].x=read(); fft(a,1),fft(b,1); for(ri i=0;i<lim;++i)a[i]=a[i]*b[i]; fft(a,-1); for(ri i=n;i<=n*2;++i)printf("%d\n",(int)(a[i].x+0.5)); return 0; }