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 );
106     read(a);
107     read(b);
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  阅读(333)  评论(0编辑  收藏  举报