大数乘法 V2

给出2个大整数A,B,计算A*B的结果。

输入格式

第1行:大数A 第2行:大数B (A,B的长度 <= 100000,A,B >= 0)

输出格式

输出A * B

输入样例

123456
234567

输出样例

28958703552
#include <bits/stdc++.h>
using namespace std;
#define sz(s) int(s.size())

#define super vector<int>
namespace integer {
//    using super = vector<int>;
    const int base_digits = 9;
    const int base = 1000000000;
    super& trim(super& a) {
        while (!a.empty() && a.back() == 0) a.pop_back();
        return a;
    }
    int compare(const super& lhs, const super& rhs) {
        int cmp = sz(lhs) - sz(rhs), i = sz(lhs) - 1;
        if (cmp != 0) return cmp < 0 ? -1 : 1;
        while (i != -1 && lhs[i] == rhs[i]) i--;
        return i == -1 ? 0 : lhs[i] < rhs[i] ? -1 : 1;
    }
    inline void norm(int& a, int& k) {
        k = (a < 0 ? (a += base, -1) : a < base ? 0 : (a -= base, 1));
    }
    super add(const super& lhs, const super& rhs) {
        super res=(sz(rhs) < sz(lhs) ? lhs : rhs);
        super bit=(sz(rhs) < sz(lhs) ? rhs : lhs);
        res.push_back(0);
        int i = 0, k = 0;
        for (; i < sz(bit); i++) norm(res[i] += k + bit[i], k);
        for (; i < sz(res) && 0 < k; i++) norm(res[i] += k, k);
        return trim(res);
    }
    super sub(super res, const super& bit) {
        int i = 0, k = 0;
        for (; i < sz(bit); i++) norm(res[i] += k - bit[i], k);
        for (; i < sz(res) && k < 0; i++) norm(res[i] += k, k);
        return trim(res);
    }
    string to_string(super a) {
        string res = "";
        if (a.empty()) return "0";
        static char s[10];
        sprintf(s, "%d", a.back());
        res.append(s);
        for (int i = sz(a) - 2; ~i; i--) {
            sprintf(s, "%09d", a[i]);
            res.append(s);
        }
        return res;
    }
    super to_super(string s) {
        super res;
        for (int i = sz(s), x; 0 < i; i -= base_digits) {
            const char* p = s.c_str() + max(0, i - base_digits);
            if (i != sz(s)) s[i] = '\0';
            sscanf(p, "%09d", &x);
            res.push_back(x);
        }
        return trim(res);
    }
    #define int64 long long
    #define vll vector<int64>
    super convert_base(const super& a, int old_digits, int new_digits) {
        vll p(max(old_digits, new_digits) + 1);
        for (int i = p[0] = 1; i < sz(p); i++)
            p[i] = p[i - 1] * 10;
        super res;
        int64 cur = 0;
        for (int i = 0, cur_digits = 0; i < sz(a); i++) {
            cur += a[i] * p[cur_digits];
            cur_digits += old_digits;
            while (new_digits <= cur_digits) {
                res.push_back(cur % p[new_digits]);
                cur_digits -= new_digits;
                cur /= p[new_digits];                
            }
        }
        res.push_back(cur);
        return trim(res);
    }
    vll karatsuba(const vll& a, const vll& b) {
        int n = sz(a);
        vll res(n + n);
        if (n <= 32) {
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    res[i + j] += a[i] * b[j];
            return res;
        }
        int k = n >> 1;
        vll a1(a.begin(), a.begin() + k);
        vll a2(a.begin() + k, a.end());
        vll b1(b.begin(), b.begin() + k);
        vll b2(b.begin() + k, b.end());
        vll a1b1 = karatsuba(a1, b1);
        vll a2b2 = karatsuba(a2, b2);
        for (int i = 0; i < k; i++) a2[i] += a1[i];
        for (int i = 0; i < k; i++) b2[i] += b1[i];
        vll r = karatsuba(a2, b2);
        for (int i = 0; i < sz(a1b1); i++) r[i] -= a1b1[i];
        for (int i = 0; i < sz(a2b2); i++) r[i] -= a2b2[i];
        for (int i = 0; i < sz(r); i++) res[i + k] += r[i];
        for (int i = 0; i < sz(a1b1); i++) res[i] += a1b1[i];
        for (int i = 0; i < sz(a2b2); i++) res[i + n] += a2b2[i];
        return res;
    }
    super mul(const super& lhs, const super& rhs) {
        const int new_digits = 6;
        const int base = 1000000;
        super a6(convert_base(lhs, base_digits, new_digits));
        super b6(convert_base(rhs, base_digits, new_digits));
        vll a(a6.begin(), a6.end());
        vll b(b6.begin(), b6.end());
        while (sz(a) < sz(b)) a.push_back(0);
        while (sz(b) < sz(a)) b.push_back(0);
        if (sz(a) == 0) return super();
        while (sz(a) & (sz(a) - 1))
            a.push_back(0), b.push_back(0);
        vll c(karatsuba(a, b));
        super res;
        int64 k = 0;
        for (int i = 0; i < sz(c); i++) {
            int64 p = c[i] + k;
            res.push_back(p % base);
            k = p / base;
        }
        res = convert_base(res, new_digits, base_digits);
        return trim(res);
    }
}
using namespace integer;

istream& operator >> (istream& in, super& p) {
    string s; in >> s;
    p = to_super(s);
    return in;
}

ostream& operator << (ostream& out, super p) {
    return out << to_string(p);
}

int main() {
    ios::sync_with_stdio(false);
    super a, b;
    cin >> a >> b;
    cout << mul(a, b) << endl;
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值