BZOJ-2179: FFT快速傅立叶

作者: AmadeusChan | 来源:发表于2018-11-19 18:19 被阅读0次

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2179

    题目大意:n<=60000的高精度乘法。

    第一次写FFT,本来想照着算导敲的,然后ORZ X姐的时候听说里面的代码会很慢,所以滚去YY了个渣渣的非递归版如下。。。

    代码:


    8b82b9014a90f6035a9b73f53b12b31bb051ed5d.jpg.png
    #include <cstdio>
    
    #include <algorithm>
    
    #include <cstring>
    
    #include <cmath>
    
    #include <complex>
    
      
    
    using namespace std ;
    
      
    
    #define cd complex <double>
    
    #define PI acos(0.0)*2.0
    
    #define maxn 32768
    
    #define check( ch )( ch >='0'&& ch <='9')
    
    #define base 10000
    
    #define ll long long
    
      
    
    int s[ maxn ];
    
    cd A[ maxn ];
    
      
    
    void FFT( cd *a ,int n ,bool flag ){
    
        for(int i =0; i < n ;++ i ) s[ i ]=0;
    
        for(int i =1, j = n ; i < n ; i <<=1, j >>=1)for(int h = j >>1; h < j ;++ h ) s[ h ]|= i ;
    
        for(int i =1; i < n ; i <<=1)for(int j =0; j < i ;++ j ) s[ j + i ]|= s[ j ];
    
        for(int i =0; i < n ;++ i ) A[ i ]= a[ s[ i ]];
    
        double pi = flag ? PI :- PI ;
    
        for(int step =1; step < n ; step <<=1){
    
            cd e =exp(cd(0,2.0* pi /double( step <<1))), w =cd(1,0);
    
            for(int pos =0; pos < step ;++ pos , w *= e ){
    
                int temp = step <<1;
    
                for(int i = pos ; i < n ; i += temp ){
    
                    cd ret = A[ i ], rec = w * A[ i + step ];
    
                    A[ i ]= ret + rec , A[ i + step ]= ret - rec ;
    
                }
    
            }
    
        }
    
        if(! flag )for(int i =0; i < n ;++ i ) A[ i ]/= n ;
    
        for(int i =0; i < n ;++ i ) a[ i ]= A[ i ];
    
    }
    
     
    
    int m , len , n1[ maxn ], n2[ maxn ], st[ maxn ];
    
     
    
    void getnum(int*N ){
    
        memset( st ,0,sizeof( st ));
    
        int ch ;for( ch =getchar(  );!check( ch ); ch =getchar(  ));
    
        st[ m ]= ch -'0';
    
        for(int i = m -1; i ;-- i ) st[ i ]=getchar(  )-'0';
    
        len =0;
    
        for(int i =1; i <= m ; i +=4){
    
            int temp =0;
    
            for(int j = i +3; j >= i ;-- j ) temp = temp *10+ st[ j ];
    
            N[ len ++]= temp ;
    
        }
    
    }
    
     
    
    cd a[ maxn ], b[ maxn ], c[ maxn ];
    
    ll ans[ maxn ], ansn =0;
    
     
    
    void getint(int&t ){
    
        int ch ;for( ch =getchar(  );!check( ch ); ch =getchar(  ));
    
        t = ch -'0';
    
        for( ch =getchar(  );check( ch ); ch =getchar(  )){
    
            t = t *10+ ch -'0';
    
        }
    
    }
    
     
    
    int o[20];
    
     
    
    void putint(int t ){
    
        if( t ){
    
            o[0]=0;
    
            for(; t ; t /=10) o[++ o[0]]= t %10;
    
            while( o[0]--)putchar('0'+ o[ o[0]+1]);
    
        }else putchar('0');
    
    }
    
     
    
    int main(  ){
    
        getint( m );
    
        getnum( n1 ),getnum( n2 );
    
        int k =1; m = len <<1;
    
        for(; k < m ; k <<=1);
    
        for(int i =0; i < k ;++ i ) a[ i ]=cd( n1[ i ],0);
    
        FFT( a , k ,true);
    
        for(int i =0; i < k ;++ i ) b[ i ]=cd( n2[ i ],0);
    
        FFT( b , k ,true);
    
        for(int i =0; i < k ;++ i ) c[ i ]= a[ i ]* b[ i ];
    
        FFT( c , k ,false);
    
        for(int i =0; i < k ;++ i ) ans[ i ]=( ll )( c[ i ].real(  )+0.5);
    
        for(int i =0; i < k ;++ i ){
    
            ans[ i +1]+= ans[ i ]/ base ;
    
            ans[ i ]%= base ;
    
        }
    
        for(int i = k ; i >=0;-- i )if( ans[ i ]){
    
            ansn = i ;break;
    
        }
    
        putint(int( ans[ ansn ]));
    
        for(int i = ansn -1; i >=0;-- i ){
    
            if( ans[ i ]<1000)putchar('0');
    
            if( ans[ i ]<100)putchar('0');
    
            if( ans[ i ]<10)putchar('0');
    
            putint(int( ans[ i ]));
    
        }
    
        putchar('\n');
    
        return 0;
    
    }
    
    
    

    相关文章

      网友评论

        本文标题:BZOJ-2179: FFT快速傅立叶

        本文链接:https://www.haomeiwen.com/subject/nibafqtx.html