|
@@ -0,0 +1,145 @@
|
|
|
+#define iszero(t) (t.len==1&&t.s[0]==0)
|
|
|
+#define setlen(l,t) t.len=l;while(t.len>1&&t.s[t.len-1]==0) t.len--
|
|
|
+const int maxlen=100;
|
|
|
+struct bigint {
|
|
|
+ int len, s[maxlen];
|
|
|
+ bigint() { *this = 0; }
|
|
|
+ bigint(int a) { *this = a; }
|
|
|
+ bigint(const char *a) { *this = a; }
|
|
|
+ bigint operator=(int);
|
|
|
+ bigint operator=(const char *);
|
|
|
+ bigint operator=(const bigint &); //Optional
|
|
|
+ friend ostream &operator<<(ostream &, const bigint &);
|
|
|
+ bigint operator+(const bigint &);
|
|
|
+ bigint operator-(const bigint &);
|
|
|
+ bigint operator*(const bigint &);
|
|
|
+ bigint operator/(const bigint &); //Require - cmp
|
|
|
+ bigint operator%(const bigint &); //Require - cmp
|
|
|
+ static int cmp(const bigint &, const bigint &);
|
|
|
+ static bigint sqrt(const bigint &); //Require - * cmp
|
|
|
+};
|
|
|
+bigint bigint::operator=(int a) {
|
|
|
+ len = 0;
|
|
|
+ do {
|
|
|
+ s[len++] = a % 10;
|
|
|
+ a /= 10;
|
|
|
+ } while (a > 0);
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+bigint bigint::operator=(const char *a) {
|
|
|
+ len = strlen(a);
|
|
|
+ for (int i = 0; i < len; i++) s[i] = a[len - i - 1] - '0';
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+bigint bigint::operator=(const bigint &a) {
|
|
|
+ len = a.len;
|
|
|
+ memcpy(s, a.s, sizeof(*s) * len);
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+ostream& operator<<(ostream &os,const bigint &a) {
|
|
|
+ for (int i = a.len - 1; i >= 0; i--) os << a.s[i];
|
|
|
+ return os;
|
|
|
+}
|
|
|
+bigint bigint::operator+(const bigint &a) {
|
|
|
+ bigint b;
|
|
|
+ b.s[b.len = max(len, a.len)] = 0;
|
|
|
+ for (int i = 0; i < b.len; i++) b.s[i] = (i < len ? s[i] : 0) + (i < a.len ? a.s[i] : 0);
|
|
|
+ for (int i = 0; i < b.len; i++)
|
|
|
+ if (b.s[i] >= 10) {
|
|
|
+ b.s[i] -= 10;
|
|
|
+ b.s[i + 1]++;
|
|
|
+ }
|
|
|
+ if (b.s[b.len]) b.len++;
|
|
|
+ return b;
|
|
|
+}
|
|
|
+//Make sure *this>=a
|
|
|
+bigint bigint::operator-(const bigint &a) {
|
|
|
+ bigint b;
|
|
|
+ for (int i = 0; i < len; i++) b.s[i] = s[i] - (i < a.len ? a.s[i] : 0);
|
|
|
+ for (int i = 0; i < len; i++)
|
|
|
+ if (b.s[i] < 0) {
|
|
|
+ b.s[i] += 10;
|
|
|
+ b.s[i + 1]--;
|
|
|
+ }
|
|
|
+ setlen(len, b);
|
|
|
+ return b;
|
|
|
+}
|
|
|
+bigint bigint::operator*(const bigint &a) {
|
|
|
+ bigint b;
|
|
|
+ memset(b.s, 0, sizeof(*s) * (len + a.len + 1));
|
|
|
+ for (int i = 0; i < len; i++)
|
|
|
+ for (int j = 0; j < a.len; j++) b.s[i + j] += s[i] * a.s[j];
|
|
|
+ for (int i = 0; i < len + a.len; i++) {
|
|
|
+ b.s[i + 1] += b.s[i] / 10;
|
|
|
+ b.s[i] %= 10;
|
|
|
+ }
|
|
|
+ setlen(len + a.len + 1, b);
|
|
|
+ return b;
|
|
|
+}
|
|
|
+bigint bigint::operator/(const bigint &a) {
|
|
|
+ bigint b, c;
|
|
|
+ for (int i = len - 1; i >= 0; i--) {
|
|
|
+ if (!iszero(b)) {
|
|
|
+ for (int j = b.len; j > 0; j--) b.s[j] = b.s[j - 1];
|
|
|
+ b.len++;
|
|
|
+ }
|
|
|
+ b.s[0] = s[i];
|
|
|
+ c.s[i] = 0;
|
|
|
+ while (cmp(b, a) >= 0) {
|
|
|
+ b = b - a;
|
|
|
+ c.s[i]++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ setlen(len, c);
|
|
|
+ return c;
|
|
|
+}
|
|
|
+bigint bigint::operator%(const bigint &a) {
|
|
|
+ bigint b;
|
|
|
+ for (int i = len - 1; i >= 0; i--) {
|
|
|
+ if (!iszero(b)) {
|
|
|
+ for (int j = b.len; j > 0; j--) b.s[j] = b.s[j - 1];
|
|
|
+ b.len++;
|
|
|
+ }
|
|
|
+ b.s[0] = s[i];
|
|
|
+ while (cmp(b, a) >= 0) b = b - a;
|
|
|
+ }
|
|
|
+ return b;
|
|
|
+}
|
|
|
+int bigint::cmp(const bigint &a,const bigint &b) {
|
|
|
+ if (a.len < b.len) return -1;
|
|
|
+ else if (a.len > b.len) return 1;
|
|
|
+ for (int i = a.len - 1; i >= 0; i--)
|
|
|
+ if (a.s[i] != b.s[i]) return a.s[i] - b.s[i];
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+bigint bigint::sqrt(const bigint &a) {
|
|
|
+ int n = (a.len - 1) / 2, p;
|
|
|
+ bigint b, d;
|
|
|
+ b.len = n + 1;
|
|
|
+ for (int i = n; i >= 0; i--) {
|
|
|
+ if (!iszero(d)) {
|
|
|
+ for (int j = d.len + 1; j > 1; j--) d.s[j] = d.s[j - 2];
|
|
|
+ d.s[0] = a.s[i * 2];
|
|
|
+ d.s[1] = a.s[i * 2 + 1];
|
|
|
+ d.len += 2;
|
|
|
+ }
|
|
|
+ else d = a.s[i * 2] + (i * 2 + 1 < a.len ? a.s[i * 2 + 1] * 10 : 0);
|
|
|
+ bigint c;
|
|
|
+ c.s[1] = 0;
|
|
|
+ for (int j = 1; j <= n - i; j++) {
|
|
|
+ c.s[j] += b.s[i + j] << 1;
|
|
|
+ if (c.s[j] >= 10) {
|
|
|
+ c.s[j + 1] = 1;
|
|
|
+ c.s[j] -= 10;
|
|
|
+ } else c.s[j + 1] = 0;
|
|
|
+ }
|
|
|
+ c.len = n - i + 1 + c.s[n - i + 1];
|
|
|
+ for (p = 1; ; p++) {
|
|
|
+ c.s[0] = p;
|
|
|
+ if (cmp(d, c * p) < 0) break;
|
|
|
+ }
|
|
|
+ b.s[i] = c.s[0] = p - 1;
|
|
|
+ d = d - c * (p - 1);
|
|
|
+ }
|
|
|
+ return b;
|
|
|
+}
|