DuongNhi99

BIGINT

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