#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cassert>
class BigInt {
private:
std::vector<int> digits; // 小端序存储,digits[0] 是个位
bool negative; // true 表示负数,false 表示非负数
// 去除前导零(同时处理结果为 0 时的符号)
void trim() {
while (digits.size() > 1 && digits.back() == 0)
digits.pop_back();
if (digits.size() == 1 && digits[0] == 0)
negative = false;
}
// 比较绝对值大小(小端序),返回 1: |a|>|b|, 0: 相等, -1: |a|<|b|
static int absCompare(const BigInt& a, const BigInt& b) {
if (a.digits.size() != b.digits.size())
return a.digits.size() > b.digits.size() ? 1 : -1;
for (int i = a.digits.size() - 1; i >= 0; --i) {
if (a.digits[i] != b.digits[i])
return a.digits[i] > b.digits[i] ? 1 : -1;
}
return 0;
}
// 加法核心(绝对值相加),结果为正
static BigInt absAdd(const BigInt& a, const BigInt& b) {
BigInt res;
res.digits.clear();
int carry = 0;
size_t i = 0;
while (i < a.digits.size() || i < b.digits.size() || carry) {
int sum = carry;
if (i < a.digits.size()) sum += a.digits[i];
if (i < b.digits.size()) sum += b.digits[i];
res.digits.push_back(sum % 10);
carry = sum / 10;
++i;
}
res.negative = false;
return res;
}
// 减法核心(绝对值相减),要求 |a| >= |b|,结果为正
static BigInt absSub(const BigInt& a, const BigInt& b) {
BigInt res;
res.digits.clear();
int borrow = 0;
for (size_t i = 0; i < a.digits.size(); ++i) {
int diff = a.digits[i] - borrow;
if (i < b.digits.size()) diff -= b.digits[i];
if (diff < 0) {
diff += 10;
borrow = 1;
} else {
borrow = 0;
}
res.digits.push_back(diff);
}
res.negative = false;
res.trim();
return res;
}
public:
// 构造函数
BigInt() : digits{0}, negative(false) {}
BigInt(long long num) : negative(false) {
if (num < 0) {
negative = true;
num = -num;
}
do {
digits.push_back(num % 10);
num /= 10;
} while (num > 0);
}
BigInt(const std::string& s) {
if (s.empty()) {
digits.push_back(0);
negative = false;
return;
}
size_t start = 0;
negative = (s[0] == '-');
if (negative || s[0] == '+') start = 1;
for (int i = s.size() - 1; i >= (int)start; --i) {
digits.push_back(s[i] - '0');
}
trim();
}
// 转换为字符串
std::string toString() const {
if (digits.empty()) return "0";
std::string res;
if (negative) res += '-';
for (int i = digits.size() - 1; i >= 0; --i)
res += (digits[i] + '0');
return res;
}
// 比较运算符
bool operator==(const BigInt& other) const {
return negative == other.negative && digits == other.digits;
}
bool operator!=(const BigInt& other) const { return !(*this == other); }
bool operator<(const BigInt& other) const {
if (negative != other.negative) return negative;
if (negative) {
// 两个负数,绝对值大的反而小
int cmp = absCompare(*this, other);
return cmp == 1;
} else {
int cmp = absCompare(*this, other);
return cmp == -1;
}
}
bool operator>(const BigInt& other) const { return other < *this; }
bool operator<=(const BigInt& other) const { return !(*this > other); }
bool operator>=(const BigInt& other) const { return !(*this < other); }
// 加减法
BigInt operator+(const BigInt& other) const {
if (negative == other.negative) {
// 同号相加:绝对值相加,符号不变
BigInt res = absAdd(*this, other);
res.negative = negative;
return res;
} else {
// 异号相加:相当于绝对值相减,符号由绝对值大的决定
int cmp = absCompare(*this, other);
if (cmp == 0) return BigInt(0);
BigInt res;
if (cmp == 1) { // |this| > |other|
res = absSub(*this, other);
res.negative = negative; // 符号与绝对值大的相同
} else {
res = absSub(other, *this);
res.negative = other.negative;
}
return res;
}
}
BigInt operator-(const BigInt& other) const {
BigInt negOther = other;
negOther.negative = !negOther.negative;
return *this + negOther;
}
BigInt operator-() const {
BigInt res = *this;
if (res.digits.size() != 1 || res.digits[0] != 0)
res.negative = !res.negative;
return res;
}
// 乘法(普通 O(n^2) 算法,可替换为 Karatsuba)
BigInt operator*(const BigInt& other) const {
BigInt res;
res.digits.assign(digits.size() + other.digits.size(), 0);
for (size_t i = 0; i < digits.size(); ++i) {
int carry = 0;
for (size_t j = 0; j < other.digits.size(); ++j) {
long long prod = (long long)digits[i] * other.digits[j] + res.digits[i + j] + carry;
res.digits[i + j] = prod % 10;
carry = prod / 10;
}
if (carry) {
res.digits[i + other.digits.size()] += carry;
}
}
res.negative = negative ^ other.negative;
res.trim();
return res;
}
// 除法(高精除以高精,返回商和余数)
friend std::pair<BigInt, BigInt> divmod(const BigInt& a, const BigInt& b);
BigInt operator/(const BigInt& other) const {
return divmod(*this, other).first;
}
BigInt operator%(const BigInt& other) const {
return divmod(*this, other).second;
}
// 复合赋值运算符
BigInt& operator+=(const BigInt& other) { *this = *this + other; return *this; }
BigInt& operator-=(const BigInt& other) { *this = *this - other; return *this; }
BigInt& operator*=(const BigInt& other) { *this = *this * other; return *this; }
BigInt& operator/=(const BigInt& other) { *this = *this / other; return *this; }
BigInt& operator%=(const BigInt& other) { *this = *this % other; return *this; }
// 输入输出
friend std::ostream& operator<<(std::ostream& os, const BigInt& bi) {
os << bi.toString();
return os;
}
friend std::istream& operator>>(std::istream& is, BigInt& bi) {
std::string s;
is >> s;
bi = BigInt(s);
return is;
}
};
// 除法辅助函数(高精除以高精,使用竖式试商)
std::pair<BigInt, BigInt> divmod(const BigInt& a, const BigInt& b) {
if (b == BigInt(0)) throw std::runtime_error("Division by zero");
if (a == BigInt(0)) return {BigInt(0), BigInt(0)};
// 确定商的符号
bool resNegative = a.negative ^ b.negative;
// 取绝对值进行计算
BigInt absA = a;
absA.negative = false;
BigInt absB = b;
absB.negative = false;
if (absA < absB) return {BigInt(0), a}; // 商为0,余数为a
BigInt quotient;
BigInt remainder;
remainder.digits.clear();
// 从被除数的高位开始逐位试商
for (int i = absA.digits.size() - 1; i >= 0; --i) {
// 将当前余数左移一位(乘以10),加上被除数的下一位
remainder.digits.insert(remainder.digits.begin(), absA.digits[i]);
remainder.trim();
// 试商:在 0-9 之间找到最大的 q 使得 q * absB <= remainder
int q = 0;
int left = 0, right = 9;
while (left <= right) {
int mid = (left + right) / 2;
BigInt prod = absB * BigInt(mid);
if (prod <= remainder) {
q = mid;
left = mid + 1;
} else {
right = mid - 1;
}
}
quotient.digits.push_back(q);
BigInt prod = absB * BigInt(q);
remainder = remainder - prod;
remainder.trim();
}
// 此时 quotient.digits 是从高位到低位存储的,需要反转成小端序
std::reverse(quotient.digits.begin(), quotient.digits.end());
quotient.trim();
quotient.negative = resNegative;
remainder.negative = a.negative; // 余数符号与被除数一致
return {quotient, remainder};
}
// 示例用法
int main() {
BigInt a("12345678901234567890");
BigInt b("98765432109876543210");
std::cout << "a = " << a << "\nb = " << b << std::endl;
std::cout << "a + b = " << a + b << std::endl;
std::cout << "a - b = " << a - b << std::endl;
std::cout << "a * b = " << a * b << std::endl;
std::cout << "a / b = " << a / b << std::endl;
std::cout << "a % b = " << a % b << std::endl;
return 0;
}