bzoj2194 快速傅立叶之二 FFT

2194: 快速傅立叶之二

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 1697  Solved: 1004
[Submit][Status][Discuss]

5
3 1
2 4
1 1
2 4
1 4

24
12
10
6
1

HINT

c[i+j]+=a[i]*b[j]

 1 #pragma GCC optimize(2)
2 #pragma G++ optimize(2)
3 #include<cstdio>
4 #include<cmath>
5 #include<iostream>
6 #include<algorithm>
7 #include<cstring>
8
9 #define N 300007
10 #define pi acos(-1)
11 using namespace std;
13 {
14     int x=0,f=1;char ch=getchar();
15     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
16     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
17     return x*f;
18 }
19
20 int n,m,L;
21 int rev[N];
22 struct comp
23 {
24     double r,v;
25     inline comp operator+(const comp &a){return (comp){r+a.r,v+a.v};}
26     inline comp operator-(const comp &a){return (comp){r-a.r,v-a.v};}
27     inline comp operator*(const comp &a){return (comp){r*a.r-v*a.v,r*a.v+v*a.r};}
28 }a[N],b[N];
29
30 void FFT(comp *a,int f)
31 {
32     for (int i=0;i<n;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
33     for (int i=1;i<n;i<<=1)
34     {
35         comp wn=(comp){cos(pi/i),f*sin(pi/i)};
36         for (int j=0;j<n;j+=(i<<1))
37         {
38             comp w=(comp){1,0};
39             for (int k=0;k<i;k++,w=w*wn)
40             {
41                 comp x=a[j+k],y=w*a[j+k+i];
42                 a[j+k]=x+y,a[j+k+i]=x-y;
43             }
44         }
45     }
46     if(f==-1)for (int i=0;i<n;i++)a[i].r/=n;
47 }
48 int main()
49 {
51     for(int i=0;i<=n;i++)
53     for(n=1;n<=m;n<<=1,L++);
54     if(L)L--;
55     for(int i=0;i<n;i++)
56         rev[i]=(rev[i>>1]>>1)|((i&1)<<L);
57     FFT(a,1),FFT(b,1);
58     for (int i=0;i<n;i++)a[i]=a[i]*b[i];
59     FFT(a,-1);
60     for (int i=m/2;i<=m;i++)
61         printf("%d\n",(int)(a[i].r+0.5));
62 }

posted @ 2018-03-08 20:37  Kaiser-  阅读(104)  评论(0编辑  收藏  举报