[带符号大整数模板]vector版

  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 };
View Code

 

posted @ 2015-03-30 04:51  jklongint  阅读(231)  评论(0编辑  收藏  举报