高精全家桶


#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;

class bigint {
	private:
		vector 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:
		inline 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;
		}
		inline 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;
		}

		inline 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;
		}

		inline 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:
		inline 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);
			}
		}

		inline 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);
			}
		}

		inline 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);
			}
		}

		inline 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);
			}
		}

		inline 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;
		}
		inline bigint operator *= (const bigint a) {
			bigint b;
			b = (*this) * a;
			*this = b;
			return *this;
		}
		inline 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;
		}
		inline 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;
		}
		inline 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;
		}
		inline bigint operator /= (bigint a) {
			bigint b;
			b = (*this) / a;
			(*this) = b;
			return b;
		}
		inline 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;
		}
		inline 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;
		}
		inline 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;
		}
		inline bigint operator %= (const bigint a) {
			bigint b;
			b = (*this) % a;
			(*this) = b;
			return *this;
		}
		inline bigint operator + (const ll num) {
			bigint temp;
			temp = num;
			return (*this) + temp;
		}
		inline bigint operator - (const ll num) {
			bigint temp;
			temp = num;
			return (*this) - temp;
		}
		inline bigint operator * (const ll num) {
			bigint temp;
			temp = num;
			return (*this) * temp;
		}
		inline bigint operator += (const ll num) {
			bigint temp;
			temp = num;
			return (*this) += temp;
		}
		inline bigint operator -= (const ll num) {
			bigint temp;
			temp = num;
			return (*this) -= temp;
		}
		inline bigint operator *= (const ll num) {
			bigint temp;
			temp = num;
			return (*this) *= temp;
		}
		inline bigint& operator ++ () {
			(*this) += 1ll;
			return (*this);
		}
		inline bigint operator ++ (int) {
			bigint temp;
			temp = (*this);
			(*this) += 1ll;
			return temp;
		}
		inline bigint &operator -- () {
			(*this) -= 1ll;
			return (*this);
		}
		inline 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 
inline 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;
}