• 「HDU 1402」A * B Problem Plus


    这个标题是唬人玩儿的,虽然这题。。。名副其实

    题意

    这道题题意是大整数乘法。多组输入,每次输入两个数,一直处理到EOF为止。每组输入的数字的长度不超过50000。

    思路

    开头就已经写清楚了,这是个快速傅立叶变换的板题。当然,不知道压个八九位用long long能不能暴力过QwQ

    FFT本来就是处理多项式乘法的系数的,多项式乘法的系数运算恰好和整数乘法一致,所以就分别把两个数反转,然后用FFT求出它们相乘以后的值,然后再反转回来。

    不要忘记它们做完乘法后可能会出现进位,所以记得处理进位(我的第一次WA)

    然后别忘了初始化(第二次WA)

    另外就是HDU的cmath库里没有M_PI(这得多老了),所以自定义一下PI(下面这个值是我直接把M_PI给复制过来了)。

    FFT的板子是从OI-Wiki抄的,复数是我自己写的。

    代码

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    
    const double PI = 3.14159265358979323846264338327950288;
    using namespace std;
    
    const int maxn = 4e5 + 5;
    int rev[maxn];
    
    struct Complex {
        double x, y;
        Complex(double x = 0.0, double y = 0.0): x(x), y(y) {}
    
        Complex operator + (const Complex &rhs) {
            return Complex(this->x + rhs.x, this->y + rhs.y);
        }
        Complex operator - (const Complex &rhs) {
            return Complex(this->x - rhs.x, this->y - rhs.y);
        }
        Complex operator * (const Complex &rhs) {
            return Complex(this->x * rhs.x - this->y * rhs.y, this->x * rhs.y + this->y * rhs.x);
        }
        Complex operator / (const double rhs) {
            return Complex(this->x / rhs, this->y / rhs);
        }
    };
    
    void change(Complex y[], int len) {
        for (int i = 0; i < len; i++) {
            rev[i] = rev[i >> 1] >> 1;
            if (i & 1)
                rev[i] |= len >> 1;
        }
        for (int i = 0; i < len; i++) {
            if (i < rev[i])
                swap(y[i], y[rev[i]]);
        }
    }
    
    void FFT(Complex y[], int len, int on) {
        change(y, len);
        for (int h = 2; h <= len; h <<= 1) {
            Complex wn(cos(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;
            }
        }
    }
    
    char str1[maxn], str2[maxn];
    Complex a[maxn], b[maxn];
    int n, m, limit;
    int ans[maxn];
    
    void Assign(char *str, Complex x[], int len) {
        for (int i = 0; i < len; i++) {
            x[i].x = (double)(str[len - i - 1] - '0');
            x[i].y = 0.0;
        }
    }
    
    inline void init() {
        for (int i = n; i <= limit; i++) a[i].x = a[i].y = 0.0;
        for (int i = m; i <= limit; i++) b[i].x = b[i].y = 0.0;
        memset(ans, 0, (limit << 2));
    }
    
    int main() {
        while (scanf("%s%s", str1, str2) == 2) {
            n = strlen(str1);
            m = strlen(str2);
            limit = 1;
            while (limit <= n + m) limit <<= 1;
            init();
            Assign(str1, a, n);
            Assign(str2, b, m);
    
            FFT(a, limit, 1);
            FFT(b, limit, 1);
            for (int i = 0; i < limit; i++)
                a[i] = a[i] * b[i];
            FFT(a, limit, -1);
            for (int i = 0; i < limit; i++)
                ans[i] = int(a[i].x + 0.5);
            
            for (int i = 0; i < limit; i++) {
                ans[i + 1] += ans[i] / 10;
                ans[i] %= 10;
            }
    
            // 这里len必须初始化为n + m - 1,因为上一次n + m的值可能不为0,而且init的时候没有处理n + m - 1后面的数据
            // 就这一个破地方我调试了半个小时
            // 说到底还是太菜QAQ
            int len = n + m - 1;
            while (!ans[len] && len > 0) len--;
    
            for (int i = len; i >= 0; i--)
                putchar(ans[i] + '0');
            putchar('
    ');
        }
        return 0;
    }
    
  • 相关阅读:
    HTTP协议中GET、POST和HEAD的介绍
    Django model 字段类型清单
    MySQL的菜鸟级操作
    windows7下将Cygwin加入右键菜单,并从当前目录打开
    数组指针和指针数组的区别
    const引用与非const引用
    printf("33[1;33m ***** 33[0m ");
    C语言可变参数函数详解示例
    机顶盒demux的工作原理
    机顶盒的工作原理
  • 原文地址:https://www.cnblogs.com/icysky/p/14018045.html
Copyright © 2020-2023  润新知