Advertisement
RaFiN_

Bignum

Jun 20th, 2020 (edited)
1,567
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.82 KB | None | 0 0
  1. const int base = 1000000000;
  2. const int base_digits = 9;
  3.  
  4. struct bigint {
  5.     vector<int> a;
  6.     int sign;
  7.  
  8.     bigint() :
  9.         sign(1) {
  10.     }
  11.  
  12.     bigint(long long v) {
  13.         *this = v;
  14.     }
  15.  
  16.     bigint(const string &s) {
  17.         read(s);
  18.     }
  19.  
  20.     void operator=(const bigint &v) {
  21.         sign = v.sign;
  22.         a = v.a;
  23.     }
  24.  
  25.     void operator=(long long v) {
  26.         sign = 1;
  27.         if (v < 0)
  28.             sign = -1, v = -v;
  29.         for (; v > 0; v = v / base)
  30.             a.push_back(v % base);
  31.     }
  32.  
  33.     bigint operator+(const bigint &v) const {
  34.         if (sign == v.sign) {
  35.             bigint res = v;
  36.  
  37.             for (int i = 0, carry = 0; i < (int) max(a.size(), v.a.size()) || carry; ++i) {
  38.                 if (i == (int) res.a.size())
  39.                     res.a.push_back(0);
  40.                 res.a[i] += carry + (i < (int) a.size() ? a[i] : 0);
  41.                 carry = res.a[i] >= base;
  42.                 if (carry)
  43.                     res.a[i] -= base;
  44.             }
  45.             return res;
  46.         }
  47.         return *this - (-v);
  48.     }
  49.  
  50.     bigint operator-(const bigint &v) const {
  51.         if (sign == v.sign) {
  52.             if (abs() >= v.abs()) {
  53.                 bigint res = *this;
  54.                 for (int i = 0, carry = 0; i < (int) v.a.size() || carry; ++i) {
  55.                     res.a[i] -= carry + (i < (int) v.a.size() ? v.a[i] : 0);
  56.                     carry = res.a[i] < 0;
  57.                     if (carry)
  58.                         res.a[i] += base;
  59.                 }
  60.                 res.trim();
  61.                 return res;
  62.             }
  63.             return -(v - *this);
  64.         }
  65.         return *this + (-v);
  66.     }
  67.  
  68.     void operator*=(int v) {
  69.         if (v < 0)
  70.             sign = -sign, v = -v;
  71.         for (int i = 0, carry = 0; i < (int) a.size() || carry; ++i) {
  72.             if (i == (int) a.size())
  73.                 a.push_back(0);
  74.             long long cur = a[i] * (long long) v + carry;
  75.             carry = (int) (cur / base);
  76.             a[i] = (int) (cur % base);
  77.             //asm("divl %%ecx" : "=a"(carry), "=d"(a[i]) : "A"(cur), "c"(base));
  78.         }
  79.         trim();
  80.     }
  81.  
  82.     bigint operator*(int v) const {
  83.         bigint res = *this;
  84.         res *= v;
  85.         return res;
  86.     }
  87.  
  88.     friend pair<bigint, bigint> divmod(const bigint &a1, const bigint &b1) {
  89.         int norm = base / (b1.a.back() + 1);
  90.         bigint a = a1.abs() * norm;
  91.         bigint b = b1.abs() * norm;
  92.         bigint q, r;
  93.         q.a.resize(a.a.size());
  94.  
  95.         for (int i = a.a.size() - 1; i >= 0; i--) {
  96.             r *= base;
  97.             r += a.a[i];
  98.             int s1 = r.a.size() <= b.a.size() ? 0 : r.a[b.a.size()];
  99.             int s2 = r.a.size() <= b.a.size() - 1 ? 0 : r.a[b.a.size() - 1];
  100.             int d = ((long long) base * s1 + s2) / b.a.back();
  101.             r -= b * d;
  102.             while (r < 0)
  103.                 r += b, --d;
  104.             q.a[i] = d;
  105.         }
  106.  
  107.         q.sign = a1.sign * b1.sign;
  108.         r.sign = a1.sign;
  109.         q.trim();
  110.         r.trim();
  111.         return make_pair(q, r / norm);
  112.     }
  113.  
  114.     bigint operator/(const bigint &v) const {
  115.         return divmod(*this, v).first;
  116.     }
  117.  
  118.     bigint operator%(const bigint &v) const {
  119.         return divmod(*this, v).second;
  120.     }
  121.  
  122.     void operator/=(int v) {
  123.         if (v < 0)
  124.             sign = -sign, v = -v;
  125.         for (int i = (int) a.size() - 1, rem = 0; i >= 0; --i) {
  126.             long long cur = a[i] + rem * (long long) base;
  127.             a[i] = (int) (cur / v);
  128.             rem = (int) (cur % v);
  129.         }
  130.         trim();
  131.     }
  132.  
  133.     bigint operator/(int v) const {
  134.         bigint res = *this;
  135.         res /= v;
  136.         return res;
  137.     }
  138.  
  139.     int operator%(int v) const {
  140.         if (v < 0)
  141.             v = -v;
  142.         int m = 0;
  143.         for (int i = a.size() - 1; i >= 0; --i)
  144.             m = (a[i] + m * (long long) base) % v;
  145.         return m * sign;
  146.     }
  147.  
  148.     void operator+=(const bigint &v) {
  149.         *this = *this + v;
  150.     }
  151.     void operator-=(const bigint &v) {
  152.         *this = *this - v;
  153.     }
  154.     void operator*=(const bigint &v) {
  155.         *this = *this * v;
  156.     }
  157.     void operator/=(const bigint &v) {
  158.         *this = *this / v;
  159.     }
  160.  
  161.     bool operator<(const bigint &v) const {
  162.         if (sign != v.sign)
  163.             return sign < v.sign;
  164.         if (a.size() != v.a.size())
  165.             return a.size() * sign < v.a.size() * v.sign;
  166.         for (int i = a.size() - 1; i >= 0; i--)
  167.             if (a[i] != v.a[i])
  168.                 return a[i] * sign < v.a[i] * sign;
  169.         return false;
  170.     }
  171.  
  172.     bool operator>(const bigint &v) const {
  173.         return v < *this;
  174.     }
  175.     bool operator<=(const bigint &v) const {
  176.         return !(v < *this);
  177.     }
  178.     bool operator>=(const bigint &v) const {
  179.         return !(*this < v);
  180.     }
  181.     bool operator==(const bigint &v) const {
  182.         return !(*this < v) && !(v < *this);
  183.     }
  184.     bool operator!=(const bigint &v) const {
  185.         return *this < v || v < *this;
  186.     }
  187.  
  188.     void trim() {
  189.         while (!a.empty() && !a.back())
  190.             a.pop_back();
  191.         if (a.empty())
  192.             sign = 1;
  193.     }
  194.  
  195.     bool isZero() const {
  196.         return a.empty() || (a.size() == 1 && !a[0]);
  197.     }
  198.  
  199.     bigint operator-() const {
  200.         bigint res = *this;
  201.         res.sign = -sign;
  202.         return res;
  203.     }
  204.  
  205.     bigint abs() const {
  206.         bigint res = *this;
  207.         res.sign *= res.sign;
  208.         return res;
  209.     }
  210.  
  211.     long long longValue() const {
  212.         long long res = 0;
  213.         for (int i = a.size() - 1; i >= 0; i--)
  214.             res = res * base + a[i];
  215.         return res * sign;
  216.     }
  217.  
  218.     friend bigint gcd(const bigint &a, const bigint &b) {
  219.         return b.isZero() ? a : gcd(b, a % b);
  220.     }
  221.     friend bigint lcm(const bigint &a, const bigint &b) {
  222.         return a / gcd(a, b) * b;
  223.     }
  224.  
  225.     void read(const string &s) {
  226.         sign = 1;
  227.         a.clear();
  228.         int pos = 0;
  229.         while (pos < (int) s.size() && (s[pos] == '-' || s[pos] == '+')) {
  230.             if (s[pos] == '-')
  231.                 sign = -sign;
  232.             ++pos;
  233.         }
  234.         for (int i = s.size() - 1; i >= pos; i -= base_digits) {
  235.             int x = 0;
  236.             for (int j = max(pos, i - base_digits + 1); j <= i; j++)
  237.                 x = x * 10 + s[j] - '0';
  238.             a.push_back(x);
  239.         }
  240.         trim();
  241.     }
  242.  
  243.     friend istream& operator>>(istream &stream, bigint &v) {
  244.         string s;
  245.         stream >> s;
  246.         v.read(s);
  247.         return stream;
  248.     }
  249.  
  250.     friend ostream& operator<<(ostream &stream, const bigint &v) {
  251.         if (v.sign == -1)
  252.             stream << '-';
  253.         stream << (v.a.empty() ? 0 : v.a.back());
  254.         for (int i = (int) v.a.size() - 2; i >= 0; --i)
  255.             stream << setw(base_digits) << setfill('0') << v.a[i];
  256.         return stream;
  257.     }
  258.  
  259.     static vector<int> convert_base(const vector<int> &a, int old_digits, int new_digits) {
  260.         vector<long long> p(max(old_digits, new_digits) + 1);
  261.         p[0] = 1;
  262.         for (int i = 1; i < (int) p.size(); i++)
  263.             p[i] = p[i - 1] * 10;
  264.         vector<int> res;
  265.         long long cur = 0;
  266.         int cur_digits = 0;
  267.         for (int i = 0; i < (int) a.size(); i++) {
  268.             cur += a[i] * p[cur_digits];
  269.             cur_digits += old_digits;
  270.             while (cur_digits >= new_digits) {
  271.                 res.push_back(int(cur % p[new_digits]));
  272.                 cur /= p[new_digits];
  273.                 cur_digits -= new_digits;
  274.             }
  275.         }
  276.         res.push_back((int) cur);
  277.         while (!res.empty() && !res.back())
  278.             res.pop_back();
  279.         return res;
  280.     }
  281.  
  282.     typedef vector<long long> vll;
  283.  
  284.     static vll karatsubaMultiply(const vll &a, const vll &b) {
  285.         int n = a.size();
  286.         vll res(n + n);
  287.         if (n <= 32) {
  288.             for (int i = 0; i < n; i++)
  289.                 for (int j = 0; j < n; j++)
  290.                     res[i + j] += a[i] * b[j];
  291.             return res;
  292.         }
  293.  
  294.         int k = n >> 1;
  295.         vll a1(a.begin(), a.begin() + k);
  296.         vll a2(a.begin() + k, a.end());
  297.         vll b1(b.begin(), b.begin() + k);
  298.         vll b2(b.begin() + k, b.end());
  299.  
  300.         vll a1b1 = karatsubaMultiply(a1, b1);
  301.         vll a2b2 = karatsubaMultiply(a2, b2);
  302.  
  303.         for (int i = 0; i < k; i++)
  304.             a2[i] += a1[i];
  305.         for (int i = 0; i < k; i++)
  306.             b2[i] += b1[i];
  307.  
  308.         vll r = karatsubaMultiply(a2, b2);
  309.         for (int i = 0; i < (int) a1b1.size(); i++)
  310.             r[i] -= a1b1[i];
  311.         for (int i = 0; i < (int) a2b2.size(); i++)
  312.             r[i] -= a2b2[i];
  313.  
  314.         for (int i = 0; i < (int) r.size(); i++)
  315.             res[i + k] += r[i];
  316.         for (int i = 0; i < (int) a1b1.size(); i++)
  317.             res[i] += a1b1[i];
  318.         for (int i = 0; i < (int) a2b2.size(); i++)
  319.             res[i + n] += a2b2[i];
  320.         return res;
  321.     }
  322.  
  323.     bigint operator*(const bigint &v) const {
  324.         vector<int> a6 = convert_base(this->a, base_digits, 6);
  325.         vector<int> b6 = convert_base(v.a, base_digits, 6);
  326.         vll a(a6.begin(), a6.end());
  327.         vll b(b6.begin(), b6.end());
  328.         while (a.size() < b.size())
  329.             a.push_back(0);
  330.         while (b.size() < a.size())
  331.             b.push_back(0);
  332.         while (a.size() & (a.size() - 1))
  333.             a.push_back(0), b.push_back(0);
  334.         vll c = karatsubaMultiply(a, b);
  335.         bigint res;
  336.         res.sign = sign * v.sign;
  337.         for (int i = 0, carry = 0; i < (int) c.size(); i++) {
  338.             long long cur = c[i] + carry;
  339.             res.a.push_back((int) (cur % 1000000));
  340.             carry = (int) (cur / 1000000);
  341.         }
  342.         res.a = convert_base(res.a, 6, base_digits);
  343.         res.trim();
  344.         return res;
  345.     }
  346. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement