这是我的板子
#ifndef MATH_BIGNUM_H_
#define MATH_BIGNUM_H_ 1
#include <string.h>
#include <algorithm>
#include <string>
#include <vector>
template <typename T>
auto HasOperatorRightString(int) -> decltype(std::declval<T>() >>
std::declval<std::string&>(),
std::true_type{});
template <typename T>
std::false_type HasOperatorRightString(...);
template <typename T>
using HasOperatorRightStringT = decltype(HasOperatorRightString<T>(0));
template <typename T>
auto HasOperatorLeftChar(int) -> decltype(std::declval<T>()
<< std::declval<char>(),
std::true_type{});
template <typename T>
std::false_type HasOperatorLeftChar(...);
template <typename T>
using HasOperatorLeftCharT = decltype(HasOperatorLeftChar<T>(0));
template <typename T>
auto HasOperatorLeftInt(int) -> decltype(std::declval<T>()
<< std::declval<int>(),
std::true_type{});
template <typename T>
std::false_type HasOperatorLeftChar(...);
template <typename T>
using HasOperatorLeftIntT = decltype(HasOperatorLeftInt<T>(0));
struct bign {
using ll = long long;
static const int BIT = 8, MOD = 1e8, maxlen = 1e4 + 5;
std::vector<int> a;
bool f;
bign() { a.clear(), f = false; }
bign(const char* s) {
int i = 0, l = strlen(s), j;
if (a.clear(), f = false, s[0] == '-') i = f = true;
if (s[i] == '0') return;
j = (l - i - 1) % BIT + 1, a.push_back(0);
for (; i < l; (a.back() *= 10) += s[i++] - 48, --j)
if (!j) a.push_back(0), j = BIT;
std::reverse(a.begin(), a.end());
}
bign(const std::string& s) { *this = s.c_str(); }
bign(int x) {
a.clear(), x < 0 ? (x = -x, f = true) : (f = false);
if (x)
x < MOD ? (a.push_back(x)) : (a.push_back(x % MOD), a.push_back(x / MOD));
}
bign(ll x) {
a.clear(), x < 0 ? (x = -x, f = true) : (f = false);
while (x > MOD) a.push_back(x % MOD), x /= MOD;
a.push_back(x);
}
template <typename T>
friend typename std::enable_if<HasOperatorRightStringT<T>::value, T&>::type
operator>>(T& in, bign& x) {
std::string c;
in >> c;
x = c;
return in;
}
template <typename T>
friend typename std::enable_if<
HasOperatorLeftIntT<T>::value && HasOperatorLeftCharT<T>::value, T&>::type
operator<<(T& out, const bign& x) {
int i = x.a.size();
if (!i) return out << '0';
if (x.f) out << '-';
char sw[BIT + 1];
for (out << x.a[--i]; i--;) {
for (int j = 0; j < BIT; j++) {
sw[j] = '0';
}
sw[BIT] = '\0';
int l = BIT;
int al = x.a[i];
while (al) {
sw[--l] = al % 10 + '0';
al /= 10;
}
out << sw;
}
return out;
}
explicit operator int() {
int l = a.size(), i, r = 0;
for (i = l - 1; ~i; --i) r = r * MOD + a[i];
return f ? -r : r;
}
explicit operator ll() {
int l = a.size(), i;
ll r = 0;
for (i = l - 1; ~i; --i) r = r * MOD + a[i];
return f ? -r : r;
}
explicit operator bool() const { return !a.empty(); }
int abscmp(const bign& x) const {
int l = a.size(), o = x.a.size();
if (l != o) return l < o ? -1 : 1;
while (l--)
if (a[l] != x.a[l]) return a[l] < x.a[l] ? -1 : 1;
return 0;
}
int cmp(const bign& x) const {
if (a.empty()) return x.a.empty() ? 0 : (x.f ? 1 : -1);
if (x.a.empty()) return f ? -1 : 1;
if (!f && x.f) return 1;
if (f && !x.f) return -1;
return f ? -abscmp(x) : abscmp(x);
}
friend bool operator<(const bign& x, const bign& y) { return x.cmp(y) < 0; }
friend bool operator>(const bign& x, const bign& y) { return x.cmp(y) > 0; }
friend bool operator<=(const bign& x, const bign& y) { return x.cmp(y) <= 0; }
friend bool operator>=(const bign& x, const bign& y) { return x.cmp(y) >= 0; }
friend bool operator==(const bign& x, const bign& y) { return x.cmp(y) == 0; }
friend bool operator!=(const bign& x, const bign& y) { return x.cmp(y) != 0; }
bign& operator+() { return *this; }
bign operator-() {
bign x = *this;
return x.f ^= 1, x;
}
void add1() {
if (++a[0] == MOD) {
a.push_back(0);
for (int i = 0; a[i] == MOD; ++i) a[i] = 0, ++a[i + 1];
if (!a.back()) a.pop_back();
}
}
void sub1() {
if (--a[0] == -1) {
for (int i = 0; a[i] == -1; ++i) a[i] += MOD, --a[i + 1];
if (!a.back()) a.pop_back();
}
}
bign& operator++() {
return a.empty() ? (a.push_back(1), f = false, void())
: (f ? sub1() : add1()),
*this;
}
bign& operator--() {
return a.empty() ? (a.push_back(1), f = true, void())
: (f ? add1() : sub1()),
*this;
}
bign operator++(int) {
bign x = *this;
return a.empty() ? (a.push_back(1), f = false, void())
: (f ? sub1() : add1()),
x;
}
bign operator--(int) {
bign x = *this;
return a.empty() ? (a.push_back(1), f = true, void())
: (f ? add1() : sub1()),
x;
}
void fit() {
while (!a.empty() && !a.back()) a.pop_back();
}
void add(const bign& x) {
int i, l = a.size(), o = x.a.size(), j;
if (l < o) a.resize(o);
a.push_back(0);
for (i = 0; i < o; ++i) {
j = a[i] + x.a[i];
if (j >= MOD) j -= MOD, ++a[i + 1];
a[i] = j;
}
fit();
}
void sub(const bign& x) {
int i, l = a.size(), o = x.a.size(), j;
for (i = 0; i < o; ++i) {
j = a[i] - x.a[i];
if (j < 0) j += MOD, --a[i + 1];
a[i] = j;
}
for (i = o; i < l; ++i)
if (a[i] < 0) a[i] += MOD, --a[i + 1];
fit();
}
void mul(const bign& x) {
int i, j, l = a.size(), o = x.a.size(), k = l + o;
std::vector<long long> C(k + 2, 0);
for (i = 0; i < o; ++i)
for (j = 0; j < l; ++j) C[i + j] += x.a[i] * 1ll * a[j];
for (i = 0, a.resize(k); i < k; ++i)
C[i + 1] += C[i] / MOD, a[i] = C[i] % MOD;
fit();
}
int div(const int& x) {
int i, l = a.size();
ll w = 0;
for (i = l - 1; ~i; --i)
w = w * MOD + a[i], a[i] = w / x, w -= ll(a[i]) * x;
return fit(), w;
}
bign div(const bign& x) {
int i, l = a.size(), o = x.a.size(), j = l - o;
ll u, v, w;
bign r, k = x;
k.f = false;
if (j < 0) return r = *this, *this = 0, r;
for (i = l - 1; i > j; --i) r = r * MOD + a[i];
for (i = j, a.resize(j + 1); ~i; --i) {
r = r * MOD + a[i], u = 0, v = MOD;
while (v - u > 1) {
w = (u + v) >> 1;
if (k * w <= r)
u = w;
else
v = w;
}
a[i] = u, r -= k * a[i];
}
return fit(), r;
}
bign divnew(const bign& x) {
int i, l = a.size(), o = x.a.size(), j = l - o;
ll u, v, w;
bign r, k = x;
k.f = false;
if (j < 0) return r = *this, *this = 0, r;
for (i = l - 1; i > j; --i) r = r * MOD + a[i];
for (i = j, a.resize(j + 1); ~i; --i) {
r = r * MOD + a[i], u = 0, v = MOD;
while (v - u > 1) {
w = (u + v) >> 1;
if (k * w <= r)
u = w;
else
v = w;
}
a[i] = u, r -= k * a[i];
}
if (f) r = -r;
f = (f != x.f);
return fit(), r;
}
bign& operator+=(const bign& x) {
if (f == x.f)
add(x);
else if (abscmp(x) >= 0)
sub(x);
else {
bign y = x;
y.sub(*this), *this = y;
}
return *this;
}
bign& operator-=(const bign& x) {
if (f != x.f)
add(x);
else if (abscmp(x) >= 0)
sub(x);
else {
bign y = x;
y.sub(*this), *this = y, f = !f;
}
return *this;
}
bign& operator*=(const bign& x) { return mul(x), f = (f != x.f), *this; }
bign& operator/=(const int& x) {
return div(abs(x)), f = !((f && x < 0) || (!f && x > 0)), *this;
}
bign& operator/=(const bign& x) { return div(x), f = (f != x.f), *this; }
bign& operator/=(const ll& x) { return *this /= (bign)x; }
bign& operator%=(const int& x) {
return *this = f ? -div(abs(x)) : div(abs(x));
}
bign& operator%=(const bign& x) { return *this = (f ? -div(x) : div(x)); }
bign& operator%=(const ll& x) { return *this %= (bign)x; }
friend bign operator+(bign x, const bign& y) { return x += y, x; }
friend bign operator-(bign x, const bign& y) { return x -= y, x; }
friend bign operator*(bign x, const bign& y) { return x *= y, x; }
friend bign operator/(bign x, const ll& y) { return x /= y, x; }
friend bign operator/(bign x, const int& y) { return x /= y, x; }
friend bign operator/(bign x, const bign& y) { return x /= y, x; }
friend bign operator%(bign x, const ll& y) { return x %= y, x; }
friend bign operator%(bign x, const int& y) { return x %= y, x; }
friend bign operator%(bign x, const bign& y) { return x %= y, x; }
};
void swap(bign& x, bign& y) { std::swap(x.f, y.f), std::swap(x.a, y.a); }
bign abs(bign x) { return x.f = false, x; }
bign pow(bign a, int b) {
bign r = 1;
for (; b; b >>= 1) {
if (b & 1) r *= a;
a *= a;
}
return r;
}
bign gcd(bign a, bign b) {
bign r = 1;
while (true) {
if (!a || !b) return (a + b) * r;
while (a.a[0] >> 1 == 0 && b.a[0] >> 1 == 0) r *= 2, a /= 2, b /= 2;
while (a.a[0] >> 1 == 0) a /= 2;
while (b.a[0] >> 1 == 0) b /= 2;
if (a < b) swap(a, b);
a -= b;
}
}
#endif
在本题上可以 AC,但这个乘法很明显是有问题的,压 8 位,所以乘起来后单个位置的值可以为
(108−1)×(108−1)×⌊8104⌋很明显这个值大于 long long 可存储的最大值。
可以通过以下程序 hack 它。
#include "bignum.h"
#include <bits/stdc++.h>
int main() {
std::string a = "";
for (int i = 0; i < 1e4; i++) {
a += '9';
}
bign x(a), y(a);
std::cout << x * y << std::endl;
return 0;
}