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 }