180 lines
5.0 KiB
C++
180 lines
5.0 KiB
C++
#include <iostream>
|
||
#include <vector>
|
||
#include <string>
|
||
#include <iomanip>
|
||
#include <algorithm>
|
||
using namespace std;
|
||
|
||
/*
|
||
* 高精度整数 BigInteger(正数)
|
||
* 存储方式:vector<int> d,低位在前(little-endian)
|
||
* 每位存储 BASE = 10^4 = 10000 的一个“数字块”,即四位十进制
|
||
* 这样可以大幅提升运算效率
|
||
*/
|
||
|
||
struct BigInteger {
|
||
static const int BASE = 10000; // 一个“数字块”的进制
|
||
static const int WIDTH = 4; // 每个块的十进制位数(用于输出补零)
|
||
|
||
vector<int> d; // 数字块存储,低位在 d[0]
|
||
|
||
/* -------- 构造函数部分 -------- */
|
||
|
||
BigInteger(long long num = 0) { *this = num; }
|
||
|
||
BigInteger& operator = (long long num) {
|
||
d.clear();
|
||
do {
|
||
d.push_back(num % BASE);
|
||
num /= BASE;
|
||
} while (num > 0);
|
||
return *this;
|
||
}
|
||
|
||
BigInteger(const string& s) { *this = s; }
|
||
|
||
BigInteger& operator = (const string& s) {
|
||
d.clear();
|
||
int len = s.size();
|
||
// 每 WIDTH 位作为一个数字块从后往前解析
|
||
for (int i = len; i > 0; i -= WIDTH) {
|
||
int x = 0;
|
||
int l = max(0, i - WIDTH);
|
||
for (int j = l; j < i; j++) x = x * 10 + (s[j] - '0');
|
||
d.push_back(x);
|
||
}
|
||
trim();
|
||
return *this;
|
||
}
|
||
|
||
/* -------- 删除高位的前导零 -------- */
|
||
void trim() {
|
||
while (d.size() > 1 && d.back() == 0) d.pop_back();
|
||
}
|
||
|
||
/* -------- 比较运算符 -------- */
|
||
|
||
bool operator < (const BigInteger& b) const {
|
||
if (d.size() != b.d.size()) return d.size() < b.d.size();
|
||
for (int i = d.size() - 1; i >= 0; i--) {
|
||
if (d[i] != b.d[i]) return d[i] < b.d[i];
|
||
}
|
||
return false; // 相等则不小于
|
||
}
|
||
|
||
bool operator > (const BigInteger& b) const { return b < *this; }
|
||
bool operator <= (const BigInteger& b) const { return !(b < *this); }
|
||
bool operator >= (const BigInteger& b) const { return !(*this < b); }
|
||
bool operator == (const BigInteger& b) const { return d == b.d; }
|
||
bool operator != (const BigInteger& b) const { return !(*this == b); }
|
||
|
||
/* -------- 高精度加法 -------- */
|
||
|
||
BigInteger operator + (const BigInteger& b) const {
|
||
BigInteger c;
|
||
c.d.clear();
|
||
int carry = 0;
|
||
for (size_t i = 0; i < d.size() || i < b.d.size() || carry; i++) {
|
||
int x = carry;
|
||
if (i < d.size()) x += d[i];
|
||
if (i < b.d.size()) x += b.d[i];
|
||
c.d.push_back(x % BASE);
|
||
carry = x / BASE;
|
||
}
|
||
return c;
|
||
}
|
||
|
||
/* -------- 高精度减法(默认 *this >= b) -------- */
|
||
|
||
BigInteger operator - (const BigInteger& b) const {
|
||
BigInteger c;
|
||
c.d.clear();
|
||
int borrow = 0;
|
||
for (size_t i = 0; i < d.size(); i++) {
|
||
int x = d[i] - borrow - (i < b.d.size() ? b.d[i] : 0);
|
||
if (x < 0) { x += BASE; borrow = 1; }
|
||
else borrow = 0;
|
||
c.d.push_back(x);
|
||
}
|
||
c.trim();
|
||
return c;
|
||
}
|
||
|
||
/* -------- 高精度 * int -------- */
|
||
|
||
BigInteger operator * (int m) const {
|
||
BigInteger c;
|
||
long long carry = 0;
|
||
for (size_t i = 0; i < d.size() || carry; i++) {
|
||
long long x = carry + (long long)(i < d.size() ? d[i] : 0) * m;
|
||
c.d.push_back(x % BASE);
|
||
carry = x / BASE;
|
||
}
|
||
c.trim();
|
||
return c;
|
||
}
|
||
|
||
/* -------- 高精度乘法 O(n^2) -------- */
|
||
|
||
BigInteger operator * (const BigInteger& b) const {
|
||
BigInteger c;
|
||
c.d.assign(d.size() + b.d.size(), 0);
|
||
|
||
for (size_t i = 0; i < d.size(); i++) {
|
||
long long carry = 0;
|
||
for (size_t j = 0; j < b.d.size() || carry; j++) {
|
||
long long cur = c.d[i+j] +
|
||
(long long)d[i] * (j < b.d.size() ? b.d[j] : 0) +
|
||
carry;
|
||
c.d[i+j] = cur % BASE;
|
||
carry = cur / BASE;
|
||
}
|
||
}
|
||
c.trim();
|
||
return c;
|
||
}
|
||
|
||
/* -------- 高精度 / int,返回商,并把余数存入 r -------- */
|
||
|
||
BigInteger operator / (int m) const {
|
||
BigInteger c;
|
||
c.d.resize(d.size());
|
||
long long r = 0;
|
||
|
||
for (int i = d.size() - 1; i >= 0; i--) {
|
||
long long x = d[i] + r * BASE;
|
||
c.d[i] = x / m;
|
||
r = x % m;
|
||
}
|
||
c.trim();
|
||
return c;
|
||
}
|
||
|
||
int operator % (int m) const {
|
||
long long r = 0;
|
||
for (int i = d.size() - 1; i >= 0; i--) {
|
||
long long x = d[i] + r * BASE;
|
||
r = x % m;
|
||
}
|
||
return r;
|
||
}
|
||
|
||
/* -------- 输入输出重载 -------- */
|
||
|
||
friend ostream& operator << (ostream& os, const BigInteger& x) {
|
||
os << x.d.back();
|
||
for (int i = x.d.size() - 2; i >= 0; i--) {
|
||
os << setw(WIDTH) << setfill('0') << x.d[i];
|
||
}
|
||
return os;
|
||
}
|
||
|
||
friend istream& operator >> (istream& is, BigInteger& x) {
|
||
string s;
|
||
is >> s;
|
||
x = s;
|
||
return is;
|
||
}
|
||
};
|
||
|