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("");
    }
}
posted @ 2020-01-13 11:14  Artoriax  阅读(226)  评论(0编辑  收藏  举报