社区讨论

Karatsuba 求卡常

P1919【模板】高精度乘法 / A*B Problem 升级版参与者 2已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@lr3it3v7
此快照首次捕获于
2024/01/07 21:19
2 年前
此快照最后确认于
2024/01/08 13:53
2 年前
查看原帖
rt,求助卡常。
现在全 T,第一个点本机跑需要大概 3s。
CPP
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
char IN[10000009]; int PR[19];
const int Mod = 1e8, LEN = 8;
class bigInt {
public:
    vector<int> num; bool neg;
    void shrink() {
        int len = num.size() - 1;
        while (len >= 0 && !num[len]) {num.pop_back(), len--;}
        if (len < 0) num.push_back(0), neg = 0;
    }
    bigInt() {num.clear(); neg = 0;}
    bigInt(vector<int> a, int b) {num = a, neg = b;}
    void clear() {vector<int>().swap(num); neg = 0;}
};
bigInt operator - (const bigInt &x) {return bigInt(x.num, x.neg ^ 1);}
bool operator < (const bigInt &x, const bigInt &y) {
	if (x.neg ^ y.neg) return x.neg;
	if (x.neg) return -y < -x;
	if (x.num.size() ^ y.num.size()) return x.num.size() < y.num.size();
	for (int i = x.num.size() - 1; i >= 0; i--)
		if (x.num[i] ^ y.num[i]) return x.num[i] < y.num[i];
	return 0;
}
bigInt operator - (const bigInt &x, const bigInt &y);
bigInt operator + (const bigInt &x, const bigInt &y) {
	if (x.neg ^ y.neg) {
		if (x.neg) return y - (-x);
		else return x - (-y);
	}
	int lx = x.num.size(), ly = y.num.size(), nl = min(lx, ly), xl = max(lx, ly);
	bigInt res; res.neg = x.neg;
	for (int i = 0; i < nl; ++i) res.num.push_back(x.num[i] + y.num[i]);
	if (lx > ly) for (int i = nl; i < xl; ++i) res.num.push_back(x.num[i]);
	else for (int i = nl; i < xl; ++i) res.num.push_back(y.num[i]);
	res.num.push_back(0);
	for (int i = 0; i < xl; ++i) if (res.num[i] >= Mod) res.num[i + 1]++, res.num[i] -= Mod;
	res.shrink(); return res;
}
bigInt operator - (const bigInt &x, const bigInt &y) {
	if (x.neg || y.neg) {
		if (x.neg && y.neg) return (-y) - (-x);
		else if (x.neg) return -((-x) + y);
		else return x + (-y);
	}
	else if (x < y) return -(y - x);
	int lx = x.num.size(), ly = y.num.size(); bigInt res; res.neg = 0;
	for (int i = 0; i < ly; ++i) res.num.push_back(x.num[i] - y.num[i]);
	for (int i = ly; i < lx; ++i) res.num.push_back(x.num[i]);
	for (int i = 0; i < lx; ++i) if (res.num[i] < 0) res.num[i + 1]--, res.num[i] += Mod;
	res.shrink(); return res;
}
bigInt operator * (const bigInt &x, const bigInt &y) {
	// x=a*10^m+b, y=c*10^m+d
	// x*y=ac*10^(2m)+(ad+bc)*10^m+bd
	int lx = x.num.size(), ly = y.num.size(), n = max(lx, ly), m = (n + 1) >> 1;
	if (n <= 78) {
		bigInt res; res.num.resize(lx + ly);
		for (int i = 0; i < lx; ++i) {
			for (int j = 0; j < ly; ++j) {
				LL T = (LL)x.num[i] * y.num[j];
				res.num[i + j + 1] += ((T + res.num[i + j]) / Mod);
				(res.num[i + j] += (T % Mod)) %= Mod;
			}
		}
		res.shrink(); return res;
	}
	bigInt a, b, c, d;
	for (int i = 0; i < m && i < lx; ++i) b.num.push_back(x.num[i]);
	for (int i = 0; i < m && i < ly; ++i) d.num.push_back(y.num[i]);
	for (int i = m; i < lx; ++i) a.num.push_back(x.num[i]);
	for (int i = m; i < ly; ++i) c.num.push_back(y.num[i]);
	bigInt ac = a * c, bd = b * d, ad = (a + b) * (c + d) - ac - bd;
	ac.num.insert(ac.num.begin(), m << 1, 0), ad.num.insert(ad.num.begin(), m, 0);
	return ac + ad + bd;
}
inline void read(bigInt &x) {
    x.clear(); scanf("%s", IN); int now = 0;
    for (int i = strlen(IN) - 1; i >= 0; i -= LEN) {
        for (int j = max(i - LEN + 1, 0); j <= i; ++j)
            if (IN[j] != '-') now = now * 10 + (IN[j] ^ 48);
            else x.neg = 1;
        x.num.push_back(now), now = 0;
    }
}
inline void write(const bigInt &x, char ch) {
    if (x.neg) putchar('-');
    int len = x.num.size() - 1; bool flag = false;
    for (int i = len; i >= 0; i--) {
    	if (x.num[i] || flag) {
    		if (!flag) printf("%d", x.num[i]);
    		else {
    			for (LL j = 0, X = x.num[i]; j < LEN; ++j, X /= 10) PR[j] = X % 10;
    			for (int j = LEN - 1; j >= 0; j--) putchar(PR[j] ^ 48);
    		}
    		flag = true;
    	}
    }
    if (!flag) putchar('0'); putchar(ch);
}
int main() {
	bigInt a, b; read(a), read(b);
	write(a * b, '\n');
    return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...