zoukankan      html  css  js  c++  java
  • HDU 1402 A * B fft 板子题

      题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1402

      题目描述: 计算A * B, 其中A, B是长度小于等于50000的整数

      解题思路: 放在以前我可能会拿两个高精度的乘法来计算, 但现在我接触到了fft:  求值 -> 相乘 -> 插值。下面是一篇很好的 fft 的讲解:

            http://www.gatevin.moe/acm/fft%E7%AE%97%E6%B3%95%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/

            首先我们把A, B分解成系数表达式, 也就是十进制表示的所有系数前面的整数, 如12345就是(1,2,3,4,5), 然后fft, 板子题。  

      题目代码: 

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    
    const double PI = acos(-1.0);
    struct Complex {
        double x, y;
        Complex(double _x = 0.0, double _y = 0.0) {
            x = _x;
            y = _y;
        }
        Complex operator -(const Complex & b )const {
            return Complex(x-b.x, y-b.y);
        }
        Complex operator +(const Complex & b)const {
            return Complex(x+b.x, y+b.y);
        }
        Complex operator *(const Complex & b)const {
            return Complex(x*b.x-y*b.y, x*b.y+y*b.x);
        }
    };
    void change(Complex y[], int len) {
        int i, j, k;
        for(i = 1, j = len / 2; i < len - 1; i++ ) {
            if( i < j ) swap( y[i], y[j] );
            k = len / 2;
            while( j >= k ) {
                j -= k;
                k /= 2;
            }
            if( j < k ) j += k;
        }
    }
    void fft(Complex y[], int len, int on) {
        change( y, len );
        for( int h = 2; h <= len; h <<= 1 ) {
            Complex wn( cos(-on*2*PI/h), sin(-on*2*PI/h) );
            for( int j = 0; j < len; j += h) {
                Complex w(1, 0);
                for( int k = j; k < j + h / 2; k++ ) {
                    Complex u = y[k];
                    Complex t = w * y[k+h/2];
                    y[k] = u + t;
                    y[k+h/2] = u - t;
                    w = w * wn;
                }
            }
        }
        if( on == -1 ) {
            for( int i = 0; i < len; i++ ) {
                y[i].x /= len;
            }
        }
    }
    const int MAXN = 200010;
    Complex x1[MAXN], x2[MAXN];
    char str1[MAXN/2], str2[MAXN/2];
    int sum[MAXN];
    
    int main() {
        while( scanf( "%s%s", str1, str2 ) == 2 ) {
            int len1 = (int)strlen(str1);
            int len2 = (int)strlen(str2);
            int len = 1;
            while( len < len1 * 2 || len < len2 * 2 ) len <<= 1;
            for( int i = 0; i < len1; i++ ) {
                x1[i] = Complex(str1[len1-1-i]-'0', 0);
            }
            for( int i = len1; i < len; i++ ) {
                x1[i] = Complex(0,0);
            }
            for( int i = 0; i < len2; i++ ) {
                x2[i] = Complex(str2[len2-1-i]-'0', 0);
            }
            for( int i = len2; i < len; i++ ) {
                x2[i] = Complex(0,0);
            }
            fft( x1, len, 1 );
            fft( x2, len, 1 );
            for( int i = 0; i < len; i++ ) {
                x1[i] = x1[i] * x2[i];
            }
            fft( x1, len, -1 );
            for( int i = 0; i < len; i++ ) {
                sum[i] = (int)(x1[i].x + 0.5);
            }
            for( int i = 0; i < len; i++ ) {
                sum[i+1] += sum[i] / 10;
                sum[i] %= 10;
            }
            len = len1 + len2 -1;
            while( sum[len] <= 0 && len > 0 ) len--;
            for( int i = len; i >= 0; i-- ) {
                printf( "%c", sum[i] + '0' );
            }
            printf( "\n" );
        }
        return 0;
    }
    View Code

      思考: 多做数学题, fft, 高斯消元, 欧几里得定理等等。

  • 相关阅读:
    vector order by function and object
    C++ Tree node ,when g++ compile multiple cpp files should list them respectively
    Node.1
    asp遍历xml节点
    redis扩展安装以及在tp5中的操作
    JS中在循环内实现休眠(for循环内setTimeout延时问题)
    一种开发软件的新思路,给Web页面穿个马甲,用web页面做软件UI,用C#(或者C++等其它语言)代码做功能 碧血黄沙
    高仿QQMusic播放器,浅谈WinForm关于UI的制作 碧血黄沙
    我的站(艾网城市生活新门户)重新上线了 碧血黄沙
    用WPF开发仿QQ概念版之MessageWindow开发以及Demo下载 碧血黄沙
  • 原文地址:https://www.cnblogs.com/FriskyPuppy/p/6802852.html
Copyright © 2011-2022 走看看