# bzoj 2179 FFT快速傅立叶

  1 /**************************************************************
2     Problem: 2179
3     User: idy002
4     Language: C++
5     Result: Accepted
6     Time:1300 ms
7     Memory:10104 kb
8 ****************************************************************/
9
10 #include <cstdio>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 #include <cmath>
15 using namespace std;
16
17 typedef long long dnt;
18
19 const double eps = 1e-10;
20 const double dpi = 2*acos(-1);
21 const int N = (1<<17)+10;
22 const int P = 17;
23
24 struct Plex {
25     double x, y;
26     Plex(){}
27     Plex( double x, double y ):x(x),y(y){}
28 };
29 Plex operator-( const Plex &a ) {
30     return Plex(-a.x,-a.y);
31 }
32 Plex operator+( const Plex &a, const Plex &b ) {
33     return Plex(a.x+b.x,a.y+b.y);
34 }
35 Plex operator-( const Plex &a, const Plex &b ) {
36     return Plex(a.x-b.x,a.y-b.y);
37 }
38 Plex operator*( const Plex &a, const Plex &b ) {
39     return Plex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
40 }
41
42 int n, p;
43 Plex a[N], b[N], c[N], w[P+1];
44 Plex d[N];
45
46 void init() {
47     for( int p=0,i=1; p<=P; p++,i<<=1 ) {
48         w[p] = Plex(cos(dpi/i),sin(dpi/i));
49     }
50 }
51 void read( Plex a[N] ) {
52     static char buf[N];
53     scanf( "%s", buf );
54     int len = strlen(buf);
55     reverse( buf, buf+len );
56     for( int i=0; buf[i]; i++ )
57         a[i].x = buf[i]-'0';
58 }
59 void print( int n, Plex a[N] ) {
60     static int stk[N], top;
61     for( int i=0; i<n; i++ ) {
62         stk[i] += int(a[i].x+0.49);
63         stk[i+1] += stk[i]/10;
64         stk[i] %= 10;
65     }
66     top = n-1;
67     while( top>=1 && stk[top]==0 ) top--;
68     if( top==0 ) {
69         printf( "0\n" );
70     } else {
71         for( int i=top; i>=0; i-- )
72             printf( "%d", stk[i] );
73         printf( "\n" );
74     }
75 }
76 int reverse( int a ) {
77     int b = 0;
78     for( int i=0; i<p; i++ )
79         if( a&(1<<i) ) b |= 1<<(p-1-i);
80     return b;
81 }
82 void fft( Plex a[N], bool r ) {
83     for( int i=0; i<n; i++ ) {
84         int j=reverse(i);
85         if( i<j ) swap(a[i],a[j]);
86     }
87     for( int p=1; p<=::p; p++ ) {
88         for( int i=0; i<n; i+=(1<<p) ) {
89             Plex wo, wk;
90             int l = 1<<(p-1);
91             if( !r ) wo = w[p];
92             else wo = Plex(w[p].x,-w[p].y);
93             wk = w[0];
94             for( int j=0; j<l; j++,wk=wk*wo ) {
95                 Plex lf = a[i+j], rg = a[i+j+l];
96                 a[i+j] = lf + wk*rg;
97                 a[i+j+l] = lf - wk*rg;
98             }
99         }
100     }
101     if( r ) for( int i=0; i<n; i++ )
102             a[i].x /= n;
103 }
104 int main() {
105     scanf( "%d", &n );
108     for( p=0; (1<<p)<n; p++ );
109     p++;
110     n = 1<<p;
111     init();
112     fft(a,0);
113     fft(b,0);
114     for( int i=0; i<n; i++ )
115         c[i] = a[i]*b[i];
116     fft(c,1);
117     print(n,c);
118 }
View Code

posted @ 2015-06-30 20:55  idy002  阅读(283)  评论(0编辑  收藏  举报