• HDU-1402 A * B Problem Plus FFT模板题


    Description

    Calculate A * B.

    Input

    Each line will contain two integers A and B. Process to end of file.

    Note: the length of each integer will not exceed 50000.

    Output

    For each case, output A * B in one line.

    Sample Input

    1
    2
    1000
    2
    

    Sample Output

    2
    2000
    

    题解

    fft入门题,这里取(x=10),那么个位数就对应(x^0),十位数对应(x^1)....将对应的系数用每位上的数字代替,fft即可,点值相乘后再求逆得到系数,系数也就是结果,最后进位化简一下即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const double pi = acos(-1.0);
    const int N = 2e5 + 50;
    typedef long long ll;
    struct cp {
        double r, i;
        cp(double r = 0, double i = 0): r(r), i(i) {}
        cp operator + (const cp &b) {
            return cp(r + b.r, i + b.i);
        }
        cp operator - (const cp &b) {
            return cp(r - b.r, i - b.i);
        }
        cp operator * (const cp &b) {
            return cp(r * b.r - i * b.i, r * b.i + i * b.r);
        }
    };
    void change(cp a[], int len) {
        for (int i = 1, j = len / 2; i < len - 1; i++) {
            if (i < j) swap(a[i], a[j]);
            int k = len / 2;
            while (j >= k) {
                j -= k;
                k /= 2;
            }
            if (j < k) j += k;
        }
    }
    void fft(cp a[], int len, int op) {
        change(a, len);
        for (int h = 2; h <= len; h <<= 1) {
            cp wn(cos(-op * 2 * pi / h), sin(-op * 2 * pi / h));
            for (int j = 0; j < len; j += h) {
                cp w(1, 0);
                for (int k = j; k < j + h / 2; k++) {
                    cp u = a[k];
                    cp t = w * a[k + h / 2];
                    a[k] = u + t;
                    a[k + h / 2] = u - t;
                    w = w * wn;
                }
            }
        }
        if (op == -1) {
            for (int i = 0; i < len; i++) {
                a[i].r /= len;
            }
        }
    }
    
    cp a[N]; cp b[N];
    char sa[N], sb[N];
    int ans[N];
    
    int main() {
        while (~scanf("%s%s", sa, sb)) {
            int la = strlen(sa), lb = strlen(sb);
            for (int i = 0; i < la; i++) {
                a[i] = cp(sa[la - i - 1] - '0', 0);
            }
            for (int i = 0; i < lb; i++) {
                b[i] = cp(sb[lb - i - 1] - '0', 0);
            }
            int len1 = max(la, lb);
            int len = 1;
            while (len < len1 * 2) len <<= 1;
            for (int i = la; i < len; i++) {
                a[i] = cp(0, 0);
            }
            for (int i = lb; i < len; i++) {
                b[i] = cp(0, 0);
            }
            fft(a, len, 1);
            fft(b, len, 1);
            for (int i = 0; i < len; i++) {
                a[i] = a[i] * b[i];
            }
            fft(a, len, -1);
            for (int i = 0; i < len; i++) {
                ans[i] = (int)(a[i].r + 0.5);
            }
            for (int i = 0; i < len; i++) {
                ans[i + 1] += ans[i] / 10;
                ans[i] %= 10;
            }
            len = la + lb - 1;
            while (ans[len] <= 0 && len > 0) len--;
            for (int i = len; i >= 0; i--) {
                putchar(ans[i] + '0');
            }
            puts("");
        }
    }
    
  • 相关阅读:
    [Luogu5042/UOJ #100][国家集训队互测2015]丢失的题面/ydc的题面
    [51nod1773]A国的贸易
    [GZOI2019&GXOI2019]省选GG记
    [51nod1659]数方块
    [51nod1052]最大M子段和
    [51nod1201]整数划分
    [51nod1084]矩阵取数问题 V2
    [51nod1020]逆序排列
    [BZOJ3000]Big Number
    [BZOJ1684][Usaco2005 Oct]Close Encounter
  • 原文地址:https://www.cnblogs.com/artoriax/p/12186382.html
Copyright © 2020-2023  润新知