Advertisement
t_naveen_2308

BigInt in C++

Oct 3rd, 2023 (edited)
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.67 KB | Source Code | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. using ll = long long;
  4. namespace fft
  5. {
  6.     const int mod = -1;
  7.     class cpx
  8.     {
  9.     public:
  10.         double r, i;
  11.         cpx(double _r = 0, double _i = 0) : r(_r), i(_i) {}
  12.         cpx operator+(cpx b) { return {r + b.r, i + b.i}; }
  13.         cpx operator-(cpx b) { return {r - b.r, i - b.i}; }
  14.         cpx operator*(cpx b) { return {r * b.r - i * b.i, r * b.i + i * b.r}; }
  15.         cpx operator/(double b) { return {r / b, i / b}; }
  16.         inline cpx conj() { return {r, -i}; }
  17.     };
  18.     const double PI = acos(-1);
  19.     vector<int> rev(1, 0); // rev has [base] bits
  20.     vector<cpx> roots;
  21.     int base = 0;
  22.     void precompute(int nbase)
  23.     {
  24.         if (nbase <= base)
  25.             return;
  26.         rev.resize(1 << nbase);
  27.         for (int i = 0; i < (1 << nbase); ++i)
  28.         {
  29.             rev[i] = rev[i >> 1] >> 1 | ((i & 1) << (nbase - 1));
  30.         }
  31.         roots.resize(1 << nbase);
  32.         for (; base < nbase; ++base)
  33.         {
  34.             int len = 1 << base;
  35.             double angle = 2 * PI / (1 << (base + 1));
  36.             for (int i = 0; i < len; ++i)
  37.             {
  38.                 double cur = angle * i;
  39.                 roots[len + i] = cpx(cos(cur), sin(cur));
  40.             }
  41.         }
  42.     }
  43.     void fft(vector<cpx> &a, int n = -1)
  44.     {
  45.         if (n == -1)
  46.             n = a.size();
  47.         assert((n & (n - 1)) == 0);
  48.         int zeros = __builtin_ctz(n);
  49.         precompute(zeros);
  50.         int shift = base - zeros;
  51.         for (int i = 0; i < n; ++i)
  52.         {
  53.             if (i < (rev[i] >> shift))
  54.                 swap(a[i], a[rev[i] >> shift]);
  55.         }
  56.         for (int len = 1; len < n; len <<= 1)
  57.             for (int i = 0; i < n; i += 2 * len)
  58.                 for (int j = 0; j < len; ++j)
  59.                 {
  60.                     cpx u = a[i + j], v = a[i + j + len] * roots[len + j];
  61.                     a[i + j] = u + v;
  62.                     a[i + j + len] = u - v;
  63.                 }
  64.     }
  65.     vector<cpx> fa, fb;
  66.     vector<ll> multiply(const vector<int> &a, const vector<int> &b)
  67.     {
  68.         if (a.empty() || b.empty())
  69.             return {};
  70.         int sz = a.size() + b.size() - 1;
  71.         int n = sz == 1 ? 1 : 1 << (32 - __builtin_clz(sz - 1));
  72.         if (n > fa.size())
  73.             fa.resize(n);
  74.         for (int i = 0; i < n; ++i)
  75.         {
  76.             int x = i < a.size() ? a[i] : 0;
  77.             int y = i < b.size() ? b[i] : 0;
  78.             fa[i] = cpx(x, y);
  79.         }
  80.         fft(fa, n);
  81.         cpx r(0, -0.5 / n);
  82.         for (int i = 0; i <= (n >> 1); ++i)
  83.         {
  84.             int j = (n - i) & (n - 1);
  85.             cpx x = (fa[i] + fa[j].conj()) / 2;
  86.             cpx y = (fa[i] - fa[j].conj()) * r;
  87.             fa[i] = x * y;
  88.             if (i != j)
  89.                 fa[j] = fa[i].conj();
  90.         }
  91.         fft(fa, n);
  92.         reverse(fa.begin() + 1, fa.begin() + n);
  93.         vector<ll> res(sz);
  94.         for (int i = 0; i < sz; ++i)
  95.         {
  96.             res[i] = llround(fa[i].r);
  97.         }
  98.         return res;
  99.     }
  100. } // namespace fft
  101. const int BASE = 1000; // Must be power of 10, use 1000 for FFT stability (BASE^2 * |maxNumSize| <= 1e15)
  102. const int BASE_DIGITS = log10(BASE);
  103. class BigInt
  104. {
  105. private:
  106.     bool neg = false; // false for *this == 0.
  107.     vector<int> num;
  108. public:
  109.     BigInt() {}
  110.     /* Can have leading zeros or empty (e.g. "-000123", "0123", "00", "0", ""). */
  111.     BigInt(const string &s)
  112.     {
  113.         int st = 0;
  114.         if (s[0] == '-')
  115.         {
  116.             neg = true;
  117.             st = 1;
  118.         }
  119.         for (int i = (int)s.size() - 1; i >= st; i -= BASE_DIGITS)
  120.         {
  121.             int x = 0;
  122.             for (int j = max(st, i - BASE_DIGITS + 1); j <= i; ++j)
  123.                 x = x * 10 + s[j] - '0';
  124.             num.push_back(x);
  125.         }
  126.         trim();
  127.     }
  128.     BigInt(ll m)
  129.     {
  130.         if (m < 0)
  131.             neg = true;
  132.         while (m)
  133.         {
  134.             num.push_back(abs(m % BASE));
  135.             m /= BASE;
  136.         }
  137.     }
  138.     void trim()
  139.     {
  140.         while (!num.empty() && !num.back())
  141.             num.pop_back();
  142.         if (num.empty())
  143.             neg = false;
  144.     }
  145.     bool operator<(const BigInt &v) const
  146.     {
  147.         if (neg != v.neg)
  148.             return neg > v.neg;
  149.         if (num.size() != v.num.size())
  150.             return neg ? num.size() > v.num.size() : num.size() < v.num.size();
  151.         for (int i = (int)num.size() - 1; i >= 0; --i)
  152.             if (num[i] != v.num[i])
  153.                 return neg ? num[i] > v.num[i] : num[i] < v.num[i];
  154.         return false;
  155.     }
  156.     bool operator>(const BigInt &v) const { return v < *this; }
  157.     bool operator<=(const BigInt &v) const { return !(v < *this); }
  158.     bool operator>=(const BigInt &v) const { return !(*this < v); }
  159.     bool operator==(const BigInt &v) const { return num == v.num && neg == v.neg; }
  160.     bool operator!=(const BigInt &v) const { return !(*this == v); }
  161.     BigInt operator-() const
  162.     {
  163.         BigInt ret(*this);
  164.         if (!ret.num.empty())
  165.             ret.neg = !ret.neg;
  166.         return ret;
  167.     }
  168.     BigInt &operator+=(const BigInt &x)
  169.     {
  170.         if (neg && !x.neg)
  171.             return *this = x - (-*this);
  172.         if (!neg && x.neg)
  173.             return *this -= -x;
  174.         assert(neg == x.neg);
  175.         int maxs = max(num.size(), x.num.size());
  176.         num.resize(maxs);
  177.         int carry = 0;
  178.         for (int i = 0; i < maxs; ++i)
  179.         {
  180.             int other = i >= x.num.size() ? 0 : x.num[i];
  181.             num[i] += other + carry;
  182.             carry = num[i] / BASE;
  183.             num[i] %= BASE;
  184.         }
  185.         if (carry)
  186.             num.push_back(carry);
  187.         return *this;
  188.     }
  189.     /* O(len(x)). Assert *this >= x >= 0. */
  190.     BigInt &subtract(const BigInt &x)
  191.     {
  192.         assert(!neg && !x.neg);
  193.         int carry = 0;
  194.         for (int i = 0; i < num.size(); ++i)
  195.         {
  196.             int other = i >= x.num.size() ? 0 : x.num[i];
  197.             num[i] -= other + carry;
  198.             carry = num[i] < 0;
  199.             if (carry)
  200.                 num[i] += BASE;
  201.         }
  202.         trim();
  203.         return *this;
  204.     }
  205.     BigInt &operator-=(const BigInt &x)
  206.     {
  207.         if (neg && !x.neg)
  208.             return *this = -(-*this + x);
  209.         if (x.neg)
  210.             return *this += -x;
  211.         assert(!neg && !x.neg);
  212.         if (*this < x)
  213.         {
  214.             BigInt y = *this;
  215.             *this = x;
  216.             return *this = -subtract(y);
  217.         }
  218.         return subtract(x);
  219.     }
  220.     /* O(len(this)) + O(1) if |m|*BASE fits in ll.
  221.     Fallbacks to BigInt multiplication if |m|*BASE doesn't fit in ll. */
  222.     BigInt &operator*=(ll m)
  223.     {
  224.         const ll MX = LLONG_MAX / BASE;
  225.         if (m < -MX || m > MX)
  226.             return *this *= BigInt(m);
  227.         neg ^= m < 0;
  228.         m = abs(m);
  229.         ll carry = 0;
  230.         for (int i = 0; i < num.size(); ++i)
  231.         {
  232.             ll v = num[i] * m + carry;
  233.             carry = v / BASE; // carry < m always.
  234.             num[i] = v % BASE;
  235.         }
  236.         while (carry)
  237.         {
  238.             num.push_back(carry % BASE);
  239.             carry /= BASE;
  240.         }
  241.         trim();
  242.         return *this;
  243.     }
  244.     /* O(L log L) where L = len(this) + len(x) */
  245.     BigInt &operator*=(const BigInt &x)
  246.     {
  247.         if (num.empty())
  248.             return *this;
  249.         neg ^= x.neg;
  250.         auto c = fft::multiply(num, x.num);
  251.         num.resize(c.size());
  252.         ll carry = 0;
  253.         for (int i = 0; i < c.size(); ++i)
  254.         {
  255.             c[i] += carry;
  256.             carry = c[i] / BASE;
  257.             num[i] = c[i] % BASE;
  258.         }
  259.         if (carry)
  260.             num.push_back(carry);
  261.         trim();
  262.         return *this;
  263.     }
  264.     /* O(len(this)) if |d|*BASE fits in ll.
  265.     Fallbacks to BigInt if |d|*BASE doesn't fit in ll. */
  266.     ll divideAndRemainder(ll d)
  267.     {
  268.         assert(d != 0);
  269.         const ll MX = LLONG_MAX / BASE;
  270.         if (d < -MX || d > MX)
  271.             return divideAndRemainder(BigInt(d)).val();
  272.         bool wasNeg = neg;
  273.         neg ^= d < 0;
  274.         d = abs(d);
  275.         ll cur = 0;
  276.         vector<int> ret(num.size());
  277.         for (int i = (int)num.size() - 1; i >= 0; --i)
  278.         {
  279.             cur *= BASE;
  280.             cur += num[i];
  281.             ret[i] = cur / d;
  282.             cur %= d;
  283.         }
  284.         swap(num, ret);
  285.         trim();
  286.         return wasNeg ? -cur : cur;
  287.     }
  288.     BigInt &operator/=(ll v)
  289.     {
  290.         divideAndRemainder(v);
  291.         return *this;
  292.     }
  293.     BigInt &operator%=(ll v)
  294.     {
  295.         ll remainder = divideAndRemainder(v);
  296.         return *this = BigInt(remainder);
  297.     }
  298.     /* O(len(this) * len(b) * log2(BASE)) */
  299.     BigInt divideAndRemainder(BigInt b)
  300.     {
  301.         assert(!b.num.empty());
  302.         bool wasNeg = neg;
  303.         neg ^= b.neg;
  304.         b.neg = false;
  305.         BigInt cur;
  306.         vector<int> ret(num.size());
  307.         for (int i = (int)num.size() - 1; i >= 0; --i)
  308.         {
  309.             cur *= BASE;
  310.             cur += num[i];
  311.             int lo = 0, hi = BASE - 1;
  312.             while (lo < hi)
  313.             {
  314.                 int d = (lo + hi + 1) >> 1;
  315.                 if (b * d > cur)
  316.                     hi = d - 1;
  317.                 else
  318.                     lo = d;
  319.             }
  320.             cur -= b * lo;
  321.             ret[i] = lo;
  322.         }
  323.         swap(num, ret);
  324.         trim();
  325.         if (wasNeg && !cur.num.empty())
  326.             cur.neg = true;
  327.         return cur;
  328.     }
  329.     BigInt &operator/=(const BigInt &x)
  330.     {
  331.         divideAndRemainder(x);
  332.         return *this;
  333.     }
  334.     BigInt &operator%=(const BigInt &x) { return *this = divideAndRemainder(x); }
  335.     friend BigInt operator+(BigInt a, const BigInt &b) { return a += b; }
  336.     friend BigInt operator-(BigInt a, const BigInt &b) { return a -= b; }
  337.     friend BigInt operator*(ll a, BigInt b) { return b *= a; }
  338.     friend BigInt operator*(BigInt a, ll b) { return a *= b; }
  339.     friend BigInt operator*(BigInt a, const BigInt &b) { return a *= b; }
  340.     friend BigInt operator/(BigInt a, ll b) { return a /= b; }
  341.     friend BigInt operator/(BigInt a, const BigInt &b) { return a /= b; }
  342.     friend BigInt operator%(BigInt a, ll b) { return a %= b; }
  343.     friend BigInt operator%(BigInt a, const BigInt &b) { return a %= b; }
  344.     BigInt &operator++() { return *this += 1; }
  345.     BigInt &operator--() { return *this -= 1; }
  346.     BigInt operator++(int)
  347.     {
  348.         BigInt ret(*this);
  349.         *this += 1;
  350.         return ret;
  351.     }
  352.     BigInt operator--(int)
  353.     {
  354.         BigInt ret(*this);
  355.         *this -= 1;
  356.         return ret;
  357.     }
  358.     /* If a = b = 0, returns 0. Else returns gcd of |a|, |b|.
  359.     O(len(a)) if b = 0; else
  360.     O(len(a) + log(|b|)) if |b|*BASE fits in ll; else
  361.     O(len(a)*len(b)*log2(BASE) + log(|b|)). */
  362.     friend BigInt gcd(const BigInt &a, ll b)
  363.     {
  364.         if (!b)
  365.             return abs(a);
  366.         ll r = abs(a % b).val();
  367.         if (r == 0)
  368.             return abs(BigInt(b));
  369.         return __gcd(r, abs(b % r));
  370.     }
  371.     friend BigInt gcd(ll a, const BigInt &b) { return gcd(b, a); }
  372.     /* If a = b = 0, returns 0. Else returns gcd of |a|, |b|.
  373.     There are O(min(len(a),len(b)) iterations. After first 2 iterations, a',b'<=min(a,b).
  374.     O(min(len(a),len(b))^3*log2(BASE) + len(a)*len(b)*log2(BASE)). */
  375.     friend BigInt gcd(BigInt a, BigInt b)
  376.     {
  377.         a.neg = b.neg = false;
  378.         while (!b.num.empty())
  379.         {
  380.             BigInt c(b);
  381.             b = a % b;
  382.             swap(a, c);
  383.         }
  384.         return a;
  385.     }
  386.     /* Get a random BigInt from [0, n-1] in expected O(2*len(n)). */
  387.     friend BigInt randomBigInt(BigInt n)
  388.     {
  389.         static mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
  390.         assert(!n.num.empty() && !n.neg);
  391.         n--;
  392.         for (;;)
  393.         {
  394.             BigInt res;
  395.             res.num.resize(n.num.size());
  396.             for (int i = (int)n.num.size() - 1; i >= 0; --i)
  397.             {
  398.                 int mx = (i + 1 == n.num.size()) ? n.num[i] : BASE - 1;
  399.                 res.num[i] = rng() % (mx + 1);
  400.             }
  401.             res.trim();
  402.             if (res <= n)
  403.                 return res;
  404.         }
  405.         assert(false);
  406.     }
  407.     friend BigInt abs(BigInt x)
  408.     {
  409.         x.neg = false;
  410.         return x;
  411.     }
  412.     friend string to_string(const BigInt &x)
  413.     {
  414.         if (x.num.empty())
  415.             return "0";
  416.         string ret;
  417.         if (x.neg)
  418.             ret += '-';
  419.         ret += to_string(x.num.back());
  420.         string fmt = "%0" + to_string(BASE_DIGITS) + "d";
  421.         for (int i = (int)x.num.size() - 2; i >= 0; --i)
  422.         {
  423.             char buf[BASE_DIGITS + 1];
  424.             sprintf(buf, fmt.c_str(), x.num[i]);
  425.             ret += buf;
  426.         }
  427.         return ret;
  428.     }
  429.     /* Throws if doesn't fit in ll. */
  430.     ll val()
  431.     {
  432.         const unsigned long long MAX_ABS = LLONG_MAX + (unsigned ll)neg;
  433.         const unsigned long long MX = MAX_ABS / BASE;
  434.         unsigned long long ret = 0;
  435.         for (int i = (int)num.size() - 1; i >= 0; --i)
  436.         {
  437.             if (ret > MX)
  438.                 throw;
  439.             ret *= BASE;
  440.             if (ret > MAX_ABS - num[i])
  441.                 throw;
  442.             ret += num[i];
  443.         }
  444.         assert(ret <= MAX_ABS);
  445.         return neg ? -ret : ret;
  446.     }
  447.     friend ostream &operator<<(ostream &os, const BigInt &x)
  448.     {
  449.         os << to_string(x);
  450.         return os;
  451.     }
  452. };
  453. BigInt operator""_x(const char *str)
  454. {
  455.     BigInt temp(str);
  456.     return temp;
  457. }
  458. int main()
  459. {
  460.     BigInt val1, val2, val3;
  461.     val1 = 14747474747474747474_x;
  462.     val2 = 383747474747474747474_x;
  463.     val3 = val1 * val2;
  464.     cout << val3;
  465. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement