1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <cstring> 5 6 using namespace std; 7 8 typedef vector<int> vi; 9 typedef long long LL; 10 11 12 const int maxI = 1e8; 13 const int Len = 8; 14 15 struct BigInt { 16 17 vi num; 18 bool symbol; 19 20 BigInt() { num.clear(); symbol = 0; } 21 BigInt(int x) { symbol = 0; if (x < 0) { symbol = 1; x = -x; } num.push_back(x % maxI); if (x >= maxI) num.push_back(x / maxI); } 22 BigInt(bool s, vi x) { symbol = s; num = x; } 23 BigInt(char s[]) { 24 int len = strlen(s), x = 1, sum = 0, p = s[0] == '-'; 25 symbol = p; 26 for (int i = len - 1; i >= p; i--) { 27 sum += (s[i] - '0') * x; 28 x *= 10; 29 if (x == 1e8 || i == p) { 30 num.push_back(sum); 31 sum = 0; 32 x = 1; 33 } 34 } 35 while (num.back() == 0 && num.size() > 1) num.pop_back(); 36 } 37 38 void push(int x) { num.push_back(x); } 39 40 BigInt abs() const { return BigInt(false, num); } 41 42 bool smaller(const vi &a, const vi &b) const { 43 if (a.size() != b.size()) return a.size() < b.size(); 44 for (int i = a.size() - 1; i >= 0; i--) { 45 if (a[i] != b[i]) return a[i] < b[i]; 46 } 47 return 0; 48 } 49 50 bool operator < (const BigInt &p) const { 51 if (symbol && !p.symbol) return true; 52 if (!symbol && p.symbol) return false; 53 if (symbol && p.symbol) return smaller(p.num, num); 54 return smaller(num, p.num); 55 } 56 57 bool operator > (const BigInt &p) const { 58 return p < *this; 59 } 60 61 bool operator == (const BigInt &p) const { 62 return !(p < *this) && !(*this < p); 63 } 64 65 bool operator >= (const BigInt &p) const { 66 return !(*this < p); 67 } 68 69 bool operator <= (const BigInt &p) const { 70 return !(p < *this); 71 } 72 73 vi add(const vi &a, const vi &b) const { 74 vi c; 75 c.clear(); 76 int x = 0; 77 for (int i = 0; i < a.size(); i++) { 78 x += a[i]; 79 if (i < b.size()) x += b[i]; 80 c.push_back(x % maxI); 81 x /= maxI; 82 } 83 for (int i = a.size(); i < b.size(); i++) { 84 x += b[i]; 85 c.push_back(x % maxI); 86 x /= maxI; 87 } 88 if (x) c.push_back(x); 89 while (c.back() == 0 && c.size() > 1) c.pop_back(); 90 return c; 91 } 92 93 vi sub(const vi &a, const vi &b) const { 94 vi c; 95 c.clear(); 96 int x = 1; 97 for (int i = 0; i < b.size(); i++) { 98 x += maxI + a[i] - b[i] - 1; 99 c.push_back(x % maxI); 100 x /= maxI; 101 } 102 for (int i = b.size(); i < a.size(); i++) { 103 x += maxI + a[i] - 1; 104 c.push_back(x % maxI); 105 x /= maxI; 106 } 107 while (c.back() == 0 && c.size() > 1) c.pop_back(); 108 return c; 109 } 110 111 vi mul(const vi &a, const vi &b) const { 112 vi c; 113 c.resize(a.size() + b.size()); 114 for (int i = 0; i < a.size(); i++) { 115 for (int j = 0; j < b.size(); j++) { 116 LL tmp = (LL)a[i] * b[j] + c[i + j]; 117 c[i + j + 1] += tmp / maxI; 118 c[i + j] = tmp % maxI; 119 } 120 } 121 while (c.back() == 0 && c.size() > 1) c.pop_back(); 122 return c; 123 } 124 125 vi div(const vi &a, const vi &b) const { 126 vi c(a.size()), x(1, 0), y(1, 0), z(1, 0), t(1, 0); 127 y.push_back(1); 128 for (int i = a.size() - 1; i >= 0; i--) { 129 z[0] = a[i]; 130 x = add(mul(x, y), z); 131 if (smaller(x, b)) continue; 132 int l = 1, r = maxI - 1; 133 while (l < r) { 134 int m = (l + r + 1) >> 1; 135 t[0] = m; 136 if (smaller(x, mul(b, t))) r = m - 1; 137 else l = m; 138 } 139 c[i] = l; 140 t[0] = l; 141 x = sub(x, mul(b, t)); 142 } 143 while (c.back() == 0 && c.size() > 1) c.pop_back(); 144 return c; 145 } 146 147 BigInt operator + (const BigInt &p) const{ 148 if (!symbol && !p.symbol) return BigInt(false, add(num, p.num)); 149 if (!symbol && p.symbol) return *this >= p.abs()? BigInt(false, sub(num, p.num)) : BigInt(true, sub(p.num, num)); 150 if (symbol && !p.symbol) return (*this).abs() > p? BigInt(true, sub(num, p.num)) : BigInt(false, sub(p.num, num)); 151 return BigInt(true, add(num, p.num)); 152 } 153 154 BigInt operator - (const BigInt &p) const { 155 return *this + BigInt(!p.symbol, p.num); 156 } 157 158 BigInt operator * (const BigInt &p) const { 159 BigInt res(symbol ^ p.symbol, mul(num, p.num)); 160 if (res.symbol && res.num.size() == 1 && res.num[0] == 0) res.symbol = false; 161 return res; 162 } 163 164 BigInt operator / (const BigInt &p) const { 165 if (p == BigInt(0)) return p; 166 BigInt res(symbol ^ p.symbol, div(num, p.num)); 167 if (res.symbol && res.num.size() == 1 && res.num[0] == 0) res.symbol = false; 168 return res; 169 } 170 171 BigInt operator % (const BigInt &p) const { 172 return *this - *this / p * p; 173 } 174 175 void show() const { 176 if (symbol) putchar('-'); 177 printf("%d", num[num.size() - 1]); 178 for (int i = num.size() - 2; i >= 0; i--) { 179 printf("%08d", num[i]); 180 } 181 putchar(' '); 182 } 183 184 int TotalDigit() const { 185 int x = num[num.size() - 1] / 10, t = 1; 186 while (x) { 187 x /= 10; 188 t++; 189 } 190 return t + (num.size() - 1) * Len; 191 } 192 193 };