#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; const int MOD = 10000; const int BigNumSize = -1; struct BigNum { int num[BigNumSize]; int l; BigNum MoveZero(); BigNum(int x); BigNum(char * ss); bool operator < (const BigNum & o) const; BigNum operator + (const BigNum & o) const; BigNum operator - () const; BigNum operator - (const BigNum & o) const; BigNum operator * (const BigNum & o) const; BigNum operator * (const int n) const; BigNum operator / (const BigNum & o) const; //BigNum operator / (const int n) const; BigNum sqrt() const; void Print(char * s); }; BigNum BigNum::MoveZero() { while (l > 1 && num[l - 1] == 0) { l--; } return *this; } BigNum::BigNum(int x = 0) { l = 0; memset(num, 0, sizeof(num)); do { num[l++] = x % MOD; x /= MOD; } while (x); } BigNum::BigNum(char * ss) { /* //deal with the negative if (ss[0] == '-') { *this = -BigNum(ss + 1); return; } */ memset(num, 0, sizeof(num)); int len = strlen(ss); char s[10] = {0}; for (l = 0; len > 4; len -= 4) { strncpy(s, ss + len - 4, 4); num[l++] = atoi(s); } memset(s, 0, sizeof(s)); strncpy(s, ss, len); num[l++] = atoi(s); MoveZero(); return; } bool BigNum:: operator < (const BigNum & o) const { if (l != o.l) { return l < o.l; } else { int i = l - 1; while (num[i] == o.num[i]) { i--; } return i >= 0 && num[i] < o.num[i]; } } BigNum BigNum:: operator + (const BigNum & o) const { /* // deal with the negative if (num[l - 1] < 0 && o.num[o.l - 1] < 0) { return - ((-*this) + (-o)); } else if (num[l - 1] < 0) { return o - (-*this); } else if (o.num[o.l - 1] < 0) { return *this - (-o); } */ int i; BigNum sum; int carry = 0; for (i = 0; i < l || i < o.l; i++) { carry += num[i] + o.num[i]; sum.num[i] = carry % MOD; carry /= MOD; } while (carry) { sum.num[i++] = carry % MOD; carry /= MOD; } sum.l = i; return sum.MoveZero(); } BigNum BigNum:: operator - () const { BigNum tmp = *this; tmp.num[l - 1] = -tmp.num[l - 1]; return tmp; } BigNum BigNum:: operator - (const BigNum & o) const { int i; int carry = 0; BigNum Dec; if (!((*this) < o)) { for (i = 0; i < l; i++) { carry += num[i] - o.num[i] + MOD; Dec.num[i] = carry % MOD; carry /= MOD; carry--; } Dec.l = l; return Dec.MoveZero(); } else { return -(o - (* this)); } } BigNum BigNum:: operator * (const BigNum & o) const { /* // deal with the negative if (num[l - 1] < 0 && o.num[o.l - 1] < 0) { return (-*this) * (-o); } else if (num[l - 1] < 0) { return -(o * (-*this)); } else if (o.num[o.l - 1] < 0) { return -(*this * (-o)); } */ if (l > o.l) { return o * (* this); } int i; int j; BigNum Mul; int carry; for (i = 0; i < l; i++) { if (num[i] == 0) { continue; } carry = 0; Mul.l = i; for (j = 0; j < o.l; j++) { carry += num[i] * o.num[j] + Mul.num[Mul.l]; Mul.num[Mul.l++] = carry % MOD; carry /= MOD; } while (carry) { carry += Mul.num[Mul.l]; Mul.num[Mul.l++] = carry % MOD; carry /= MOD; } } return Mul.MoveZero(); } BigNum BigNum:: operator * (const int n) const { BigNum ret; if (0 == n) { return ret; } int cry = 0; int i; for (i = 0; i < l; i++) { cry += num[i] * n; ret.num[i] = cry % MOD; cry /= MOD; } while (cry) { ret.num[i++] = cry % MOD; cry /= MOD; } ret.l = i; return ret.MoveZero(); } BigNum BigNum:: operator / (const BigNum &o) const //BigNum BIgNum:: operator / (const int o) const { BigNum ret; BigNum mod; // deal with the BigNum / int //int mod = 0; int i; int left; int right; int mid; memcpy(mod.num, num + l - (o.l - 1), sizeof(int)* (o.l - 1));// mod.l = max(o.l - 1, mod.l);// ret.l = l - o.l + 1;// for (i = l - o.l; i >= 0; i--) //for (i = l - 1; i >= 0; i--) // for int { mod = mod * MOD + num[i]; left = 0; right = MOD; while (left < right - 1) { mid = (left + right) >> 1; if (mod < o * mid) { right = mid; } else { left = mid; } } mod = mod - o * left; ret.num[i] = left; } return ret.MoveZero(); } BigNum BigNum::sqrt() const { int i; int j; BigNum ret; BigNum n; BigNum tmp; for (i = l - 1; i >= 0; i--) { int tt[] = {num[i] / 100 , num[i] % 100}; for (j = 0; j < 2; j++) { n = n * 100 + tt[j]; int k = 0; tmp = ret * 20; while (1) { tmp.num[0]++; if (n < tmp * (k + 1)) { break; } k++; } tmp.num[0]--; n = n - tmp * k; ret = ret * 10 + k; } } return ret; } void BigNum::Print(char * s = "/n") { int i; printf("%d", num[l - 1]); for (i = l - 2; i >= 0; i--) { printf("%04d", num[i]); } printf("%s", s); return ; }