高精全家桶
阿新 • • 發佈:2021-08-27
高精全家桶
#include <cstdio> #include <iostream> #include <cstring> #include <vector> using namespace std; typedef long long ll; class bigint { private: vector<int> s; bool sign = false; static const int BASE = 10000; static const int WIDTH = 4; inline bool Cmp(const bigint a) { int len = s.size(); if (len < a.s.size()) return true; if (len > a.s.size()) return false; for (int i = len - 1; i; i--) { if (s[i] < a.s[i]) return true; else if (s[i] > a.s[i]) return false; } return false; } public: inline bigint &operator = (const string &str) { s.clear(); s.push_back(0); int x; int l = str.size(), len = (l - 1) / WIDTH + 1; for (register int i = s[0] == '-' ? 1 : 0; i < len; i++) { register int end = l - i * WIDTH; register int start = max(0, end - WIDTH); sscanf(str.substr(start, end - start).c_str(), "%d", &x); s.push_back(x); } if (s[0] == '-') sign = true; return *this; } inline bigint &operator = (const bigint n) { s.clear(); for (int i = 0; i < n.s.size(); i++) s.push_back(n.s[i]); sign = n.sign; return *this; } inline bigint &operator = (ll n) { s.clear(); s.push_back(0); while (n) s.push_back(n % BASE), n /= BASE; return *this; } inline bool operator < (const bigint a) const { if (sign && !a.sign) return true; if (!sign && a.sign) return false; int len = s.size(); if (len < a.s.size()) return true; if (len > a.s.size()) return false; for (int i = len - 1; i; i--) { if (s[i] < a.s[i]) return true; else if (s[i] > a.s[i]) return false; } return false; } inline bool operator == (const bigint a) const { if (sign != a.sign) return false; int len = s.size(); if (len != a.s.size()) return false; for (int i = 1; i < len; i++) if (s[i] != a.s[i]) return false; return true; } inline bool operator > (const bigint a) const { return (a < (*this)); } inline bool operator <= (const bigint a) const { return !(*this > a); } inline bool operator >= (const bigint a) const { return !(*this < a); } private: bigint add(const bigint a) const { bigint b; int j = 0; int len = s.size(), len2 = a.s.size(), len3 = min(len, len2); b.s.resize(max(len, len2)); for (int i = 1; i < len3; i++) b.s[i] = (a.s[i] + s[i] + j) % BASE, j = (a.s[i] + s[i] + j) / BASE; if (len > len2) for (int i = len3; i < len; i++) b.s[i] = (s[i] + j) % BASE, j = (s[i] + j) / BASE; else if (len < len2) for (int i = len3; i < len2; i++) b.s[i] = (a.s[i] + j) % BASE, j = (a.s[i] + j) / BASE; if (j != 0) b.s.push_back(j); int i = b.s.size() - 1; while (!b.s[i] && i > 1) b.s.pop_back(), i--; return b; } bigint reduce(bigint a) { bool vis = false; if ((*this).Cmp(a)) { bigint t; t = *this; *this = a; a = t; vis = 1; } bigint b; int j = 0; int len = s.size(), len2 = a.s.size(), len3 = min(len, len2); b.s.resize(max(len, len2)); for (int i = 1; i < len3; i++) { b.s[i] = s[i] - a.s[i] - j; if (b.s[i] < 0) b.s[i] += BASE, j = 1; else j = 0; } if (len > len2) for (int i = len3; i < len; i++) { b.s[i] = s[i] - j; if (b.s[i] < 0) b.s[i] += BASE, j = 1; else j = 0; } int i = b.s.size() - 1; while (!b.s[i] && i > 1) b.s.pop_back(), i--; if (vis) { b.sign = true; bigint t; t = *this; *this = a; a = t; } return b; } bigint add_equal(const bigint a) { int j = 0, tmp; int len = s.size(), len2 = a.s.size(), len3 = min(len, len2); s.resize(max(len, len2)); for (int i = 1; i < len3; i++) { tmp = s[i]; s[i] = (a.s[i] + s[i] + j) % BASE; j = (a.s[i] + tmp + j) / BASE; } if (len > len2) for (int i = len3; i < len; i++) { tmp = s[i]; s[i] = (s[i] + j) % BASE; j = (tmp + j) / BASE; } else if (len < len2) for (int i = len3; i < len2; i++) s[i] = (a.s[i] + j) % BASE, j = (a.s[i] + j) / BASE; if (j != 0) s.push_back(j); int i = s.size() - 1; while (!s[i] && i > 1) s.pop_back(), i--; return *this; } bigint reduce_equal(bigint a) { bool vis = false; if ((*this).Cmp(a)) { bigint t; t = *this; *this = a; a = t; vis = true; } int j = 0; int len = s.size(), len2 = a.s.size(), len3 = min(len, len2); s.resize(max(len, len2)); for (int i = 1; i < len3; i++) { s[i] = s[i] - a.s[i] - j; if (s[i] < 0) s[i] += BASE, j = 1; else j = 0; } if (len > len2) for (int i = len3; i < len; i++) { s[i] = s[i] - j; if (s[i] < 0) s[i] += BASE, j = 1; else j = 0; } int i = s.size() - 1; while (!s[i] && i > 1) s.pop_back(), i--; if (vis) sign = true; return *this; } public: bigint operator + (bigint a) { if (sign) { if (a.sign) { bigint t; t = add(a); t.sign = true; return t; } else return a.reduce(*this); } else { if (a.sign) return reduce(a); else return add(a); } } bigint operator += (bigint a) { if (sign) { if (a.sign) { bigint t; add(a); sign = true; return *this; } else return (*this) = a.reduce(*this); } else { if (a.sign) return reduce_equal(a); else return add_equal(a); } } bigint operator - (bigint a) { if (sign) { if (a.sign) return a.reduce(*this); else { bigint t; t = add(a); t.sign = true; return t; } } else { if (a.sign) return add(a); else return reduce(a); } } bigint operator -= (bigint a) { if (sign) { if (a.sign) return (*this) = a.reduce(*this); else { add_equal(a); sign = true; return *this; } } else { if (a.sign) return add_equal(a); else return reduce_equal(a); } } bigint operator * (const bigint a) { bigint b; int len = s.size(), len2 = a.s.size(); b.s.resize(len + len2 + 2); for (register int i = 1; i < len; i++) { register int temp = 0; for (register int j = 1; j < len2; j++) { b.s[i + j - 1] += s[i] * a.s[j] + temp; temp = b.s[i + j - 1] / BASE; b.s[i + j - 1] %= BASE; } b.s[i + len2 - 1] = temp; } int i = b.s.size() - 1; while (!b.s[i] && i > 1) b.s.pop_back(), i--; b.sign = sign ^ a.sign; return b; } bigint operator *= (const bigint a) { bigint b; b = (*this) * a; *this = b; return *this; } bigint operator / (ll num) { bigint a; int cur = s.size(), k = 0, q; a.s.push_back(0); while (cur > 1) { q = k * BASE + s[--cur]; a.s.push_back(q / num); k = q % num; } int c = a.s.size(); for (int i = 1; i <= c >> 1; i++) swap(a.s[i], a.s[c - i]); int i = a.s.size() - 1; while (!a.s[i] && i > 1) a.s.pop_back(), i--; return a; } bigint operator / (const bigint a) { bigint b, p, q; int cur = s.size(), digit; q.s.push_back(0); b.s.push_back(0); while (cur > 1) { digit = 0; bigint temp; temp = s[--cur]; p = q; if (p.s.size() > 1 || p.s[1] > 0) p.s.push_back(0); int tmp = 0; for (int i = 1; i < p.s.size(); i++) swap(tmp, p.s[i]); q = p.add(temp); while (!q.Cmp(a)) q.reduce_equal(a), digit++; b.s.push_back(digit); } int c = b.s.size(); for (int i = 1; i <= c >> 1; i++) swap(b.s[i], b.s[c - i]); int i = b.s.size() - 1; while (!b.s[i] && i > 1) b.s.pop_back(), i--; if (b.s.size() == 1) b.s.push_back(0); return b; } bigint operator /= (ll num) { bigint a; a.s.push_back(0); int cur = s.size(), k = 0, q; while (cur > 1) { q = k * 10 + s[--cur]; a.s.push_back(q / num); k = q % num; } int c = a.s.size(); for (int i = 1; i <= c >> 1; i++) swap(a.s[i], a.s[c - i]); int i = a.s.size() - 1; while (!a.s[i] && i > 1) a.s.pop_back(), i--; *this = a; return *this; } bigint operator /= (bigint a) { bigint b; b = (*this) / a; (*this) = b; return b; } ll operator % (const ll num) { ll cur = s.size(), k = 0, q; while (cur > 1) q = k * 10 + s[--cur], k = q % num; return k; } bigint operator % (const bigint a) { bigint p, q; register int cur = s.size(); q = 0; while (cur > 1) { bigint temp; temp = s[--cur]; p = q; if (p.s.size() > 1 || p.s[1] > 0) p.s.push_back(0); int tmp = 0; for (int i = 1; i < p.s.size(); i++) swap(tmp, p.s[i]); q = p.add(temp); while (!q.Cmp(a)) q.reduce_equal(a); } return q; } bigint operator %= (const ll num) { ll cur = s.size(), k = 0, q; while (cur > 1) q = k * 10 + s[--cur], k = q % num; *this = k; return *this; } bigint operator %= (const bigint a) { bigint b; b = (*this) % a; (*this) = b; return *this; } bigint operator + (const ll num) { bigint temp; temp = num; return (*this) + temp; } bigint operator - (const ll num) { bigint temp; temp = num; return (*this) - temp; } bigint operator * (const ll num) { bigint temp; temp = num; return (*this) * temp; } bigint operator += (const ll num) { bigint temp; temp = num; return (*this) += temp; } bigint operator -= (const ll num) { bigint temp; temp = num; return (*this) -= temp; } bigint operator *= (const ll num) { bigint temp; temp = num; return (*this) *= temp; } bigint& operator ++ () { (*this) += 1ll; return (*this); } bigint operator ++ (int) { bigint temp; temp = (*this); (*this) += 1ll; return temp; } bigint &operator -- () { (*this) -= 1ll; return (*this); } bigint operator -- (int) { bigint temp; temp = (*this); (*this) -= 1ll; return temp; } friend inline istream &operator >> (istream &in, bigint &x); friend inline ostream &operator << (ostream &out, const bigint x); friend inline void scan(bigint &a); friend inline void print(const bigint a); friend inline void swap(bigint &a, bigint &b); }; inline istream &operator >> (istream &in, bigint &x) { string s; if(!(in >> s)) return in; x = s; return in; } inline ostream &operator << (ostream &out, const bigint x) { char buf[10]; if (x.sign) out << '-'; out << x.s.back(); for (int i = x.s.size() - 2; i; i--) { sprintf(buf, "%04d", x.s[i]); for (int j = 0; j < strlen(buf); j++) out << buf[j]; } return out; } namespace IO { inline char nc() { static char buf[65536], *p1, *p2; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 65536, stdin), p1 == p2) ? EOF : *p1++; } inline int read() { char ch; int x = 0; bool f = true; while ((ch = nc()) < 48) if (ch == '-') f = false; while (ch >= 48) x = x * 10 + ch - 48, ch = nc(); return f ? x : -x; } inline ll readll() { char ch; ll x = 0; bool f = true; while ((ch = nc()) < 48) if (ch == '-') f = false; while (ch >= 48) x = x * 10 + ch - 48, ch = nc(); return f ? x : -x; } inline double readou() { char ch; double eps = 0.1, x = 0; bool f = true; while ((ch = nc()) < 48) if (ch == '-') f = false; while (ch >= 48) x = x * 10 + ch - 48, ch = nc(); if (ch == '.') while ((ch = nc()) >= 48) x += (ch - 48) * eps, eps /= 10; return f ? x : -x; } } inline void scan(bigint &a) { string str; char ch; while ((ch = IO::nc()) < 48) if (ch == '-') a.sign = true; while (ch >= 48) str.append(1, ch), ch = IO::nc(); a = str; } inline void print(const bigint a) { if (!(a.s.size() == 2 && !a.s[1]) && a.sign) putchar('-'); printf("%d", a.s.back()); for (int i = a.s.size() - 2; i; i--) printf("%04d", a.s[i]); } inline void swap(bigint &a, bigint &b) { bigint t; t = a; a = b; b = t; } template <typename T> bigint Bigint(T num) { bigint p; p = num; return p; } int main() { bigint a, b; scan(a); scan(b); print(a + b); putchar('\n'); print(a - b); putchar('\n'); print(a * b); putchar('\n'); print(a / b); putchar('\n'); print(a % b); return 0; }