BZOJ2194: 快速傅立叶之二

来源:互联网 发布:gta5优化好吗 编辑:程序博客网 时间:2024/04/29 16:34

颓了那么多天开始做题目。。

今天又去看了一下FFT 总算是全部搞懂了。。

Rader很神啊

#include<cstdio>#include<iostream>#include<cstring>#include<cmath>#include<complex> using namespace std; #define com complex<double> char c;inline void read(int &a){a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}inline void Get(int &a){a=0;do c=getchar();while(c<'0'||c>'9');    a=c-'0';}int St[1000001];int N;struct Complex_Line{int n;com *Line;inline void Begin(int t){Line=new com[n=t];}    inline void print()    {    for(int i=0;i<n;i++)   St[i]=(Line[i].real()+0.1);       St[n]=0;int len=n;if(St[len+1])len++;while(!St[len])len--;for(int i=N-1;i!=-1;i--)printf("%d\n",St[i]);     }};const  double pi=acos(-1);int rev[1000001];inline void  Beg(int Len){  int L=0,t=1;  while((1<<L)^Len)L++;  for(int i=0;i<Len;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));}inline Complex_Line Rev(Complex_Line a){Complex_Line Re;Re.Begin(a.n);for(int i=0;i<a.n;i++)  Re.Line[rev[i]]=a.Line[i];return Re;}inline Complex_Line FFT(Complex_Line t,int f){int n=t.n;Complex_Line A=Rev(t);for(int i=1;i<n;i<<=1)  {  com W0=com(cos(pi/i),f*sin(pi/i));  for(int j=0;j<n;j+=(i<<1))          {          com W(1,0);          for(int k=0;k<i;k++)              {              com x=A.Line[j+k],y=W*A.Line[j+k+i];                A.Line[j+k]=x+y;                A.Line[j+k+i]=x-y;                W*=W0;  }  }  }  if(f==-1)   for(int j=0;j<n;j++)    A.Line[j]/=n;return A;}int main(){int n;read(n);N=n;int tp=n;while(tp^(tp&-tp)){tp^=tp&-tp;}tp<<=2;int i;Complex_Line A,B;A.Begin(tp);B.Begin(tp);int j;    for(i=1;i<=n;i++)      {  read(j);  A.Line[n-i]=j;  read(j);  B.Line[i-1]=j;      }for(i=n;i<tp;i++)     A.Line[i]=com(0,0),          B.Line[i]=com(0,0);     Beg(tp);A=FFT(A,1);B=FFT(B,1);for(i=0;i<tp;i++) A.Line[i]=A.Line[i]*B.Line[i];A=FFT(A,-1);A.print();return 0;} 


0 0