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('\n');
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 };