# bzoj2194: 快速傅立叶之二

 1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <cmath>
5 #include <algorithm>
6 using namespace std;
7 const int maxn=400005;
8 const double PI=acos(-1);
9 struct node{
10     double real,imag;
11     void clear(){real=imag=0;}
12     node operator +(const node &x){return (node){real+x.real,imag+x.imag};}
13     node operator -(const node &x){return (node){real-x.real,imag-x.imag};}
14     node operator *(const node &x){return (node){real*x.real-imag*x.imag,real*x.imag+imag*x.real};}
15 }a[maxn],b[maxn],c[maxn],t1,t2,w,wn;
16 int m,n,len,rev[maxn],ans[maxn];
18     x=0; int f=1; char ch;
19     for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') f=-1;
20     for (;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; x*=f;
21 }
22 int Rev(int x){
23     int temp=0;
24     for (int i=1;i<=len;i++) temp<<=1,temp+=(x&1),x>>=1;
25     return temp;
26 }
27 void FFT(node *a,int op){
28     for (int i=0;i<n;i++) if (i<rev[i]) swap(a[i],a[rev[i]]);
29     for (int s=2;s<=n;s<<=1){
30         wn=(node){cos(2*op*PI/s),sin(2*op*PI/s)};
31         for (int i=0;i<n;i+=s){
32             w=(node){1,0};
33             for (int j=i;j<i+s/2;j++,w=w*wn){
34                 t1=a[j],t2=w*a[j+s/2];
35                 a[j]=t1+t2,a[j+s/2]=t1-t2;
36             }
37         }
38     }
39 }
40 int main(){
42     while (n<(m<<1)) n<<=1,len++;
43     for (int i=0;i<n;i++) rev[i]=Rev(i);
45     FFT(a,1),FFT(b,1);
46     for (int i=0;i<n;i++) c[i]=a[i]*b[i];
47     FFT(c,-1);
48     for (int i=0;i<n;i++) ans[i]=(int)round(c[i].real/n);
49     for (int i=m-1;i<2*m-1;i++) printf("%d\n",ans[i]);
50     return 0;
51 }
View Code

posted @ 2016-09-16 23:36  oyzx~  阅读(127)  评论(0编辑  收藏  举报