Dang_Quan_10_Tin

Bignum(Vector)

Mar 14th, 2021 (edited)
766
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.32 KB | None | 0 0
  1. /// Bignum với vector<>
  2. /// M là số chữ số ước lượng, nhớ thay đổi với các bài
  3. /// Nếu không có phép nhân thì nên đẩy BASE lên 1e17 hoặc 1e18
  4. /// a = Bignum(5) || a = Bignum("5") đều được, tuy nhiên khuyến khích dùng loại 1
  5. /// cin >> a hay a.read() đều được
  6. /// cout << a hay a.print() đều được, khuyến khích dùng loại 1
  7. /// Phép chia và phép mod chỉ dùng cho số nguyên và cho ra kết quả nguyên
  8. /// Phép nhân fft
  9.  
  10.  
  11. using cd = complex<long double>;
  12. const double PI = acos(-1);
  13. const int M = 64;
  14. const ll BASE = 1e7;
  15. const int gd = log10(BASE);
  16. const int maxn = M / gd + 1;
  17. struct Bignum
  18. {
  19.     vector<ll> a;
  20.     Bignum(ll x = 0)
  21.     {
  22.         a.reserve(maxn);
  23.         do
  24.         {
  25.             a.emplace_back(x % BASE);
  26.             x /= BASE;
  27.         } while (x);
  28.     }
  29.     Bignum(const string &s)
  30.     {
  31.         Convert(s);
  32.     }
  33.     ll stoll(const string &s)
  34.     {
  35.         ll ans(0);
  36.         for (auto i : s)
  37.             ans = ans * 10 + i - '0';
  38.         return ans;
  39.     }
  40.     void Convert(const string &s)
  41.     {
  42.         a.clear();
  43.         a.reserve(maxn);
  44.         for (int i = s.size() - 1; ~i; --i)
  45.         {
  46.             int j = max(0, i - gd + 1);
  47.             a.emplace_back(stoll(s.substr(j, i - j + 1)));
  48.             i = j;
  49.         }
  50.         fix();
  51.     }
  52.     void fix()
  53.     {
  54.         a.emplace_back(0);
  55.         for (int i = 0; i < (int)a.size() - 1; ++i)
  56.         {
  57.             a[i + 1] += a[i] / BASE;
  58.             a[i] %= BASE;
  59.             if (a[i] < 0)
  60.             {
  61.                 a[i] += BASE;
  62.                 --a[i + 1];
  63.             }
  64.         }
  65.         while ((int)a.size() > 1 && a.back() == 0)
  66.             a.pop_back();
  67.     }
  68.     Bignum &operator+=(const Bignum &x)
  69.     {
  70.         a.resize(max(a.size(), x.a.size()));
  71.         for (int i = 0; i < (int)a.size(); ++i)
  72.             a[i] += x.a[i];
  73.         fix();
  74.         return *this;
  75.     }
  76.     Bignum &operator-=(const Bignum &x)
  77.     {
  78.         a.resize(max(a.size(), x.a.size()));
  79.         for (int i = 0; i < (int)x.a.size(); ++i)
  80.             a[i] -= x.a[i];
  81.         fix();
  82.         return *this;
  83.     }
  84.     void fft(vector<cd> &a, bool invert)
  85.     {
  86.         int n = a.size();
  87.  
  88.         for (int i = 1, j = 0; i < n; i++)
  89.         {
  90.             int bit = n >> 1;
  91.             for (; j & bit; bit >>= 1)
  92.                 j ^= bit;
  93.             j ^= bit;
  94.  
  95.             if (i < j)
  96.                 swap(a[i], a[j]);
  97.         }
  98.  
  99.         for (int len = 2; len <= n; len <<= 1)
  100.         {
  101.             long double ang = 2 * PI / len * (invert ? -1 : 1);
  102.             cd wlen(cos(ang), sin(ang));
  103.             for (int i = 0; i < n; i += len)
  104.             {
  105.                 cd w(1);
  106.                 for (int j = 0; j < len / 2; j++)
  107.                 {
  108.                     cd u = a[i + j], v = a[i + j + len / 2] * w;
  109.                     a[i + j] = u + v;
  110.                     a[i + j + len / 2] = u - v;
  111.                     w *= wlen;
  112.                 }
  113.             }
  114.         }
  115.  
  116.         if (invert)
  117.         {
  118.             for (cd &x : a)
  119.                 x /= n;
  120.         }
  121.     }
  122.     Bignum &operator*=(const Bignum &x)
  123.     {
  124.         int m = 1;
  125.         while (m < (int)(a.size() + x.a.size()))
  126.             m <<= 1;
  127.         vector<cd> fa(m), fb(m);
  128.         for (int i = 0; i < (int)a.size(); ++i)
  129.             fa[i] = a[i];
  130.         for (int i = 0; i < (int)x.a.size(); ++i)
  131.             fb[i] = x.a[i];
  132.         fft(fa, false); /// dft
  133.         fft(fb, false); /// dft
  134.         for (int i = 0; i < m; i++)
  135.             fa[i] *= fb[i];
  136.         fft(fa, true); ///Interpolation
  137.         a.resize(m);
  138.         for (int i = 0; i < (int)a.size(); ++i)
  139.             a[i] = round(fa[i].real());
  140.         fix();
  141.         return *this;
  142.     }
  143.     Bignum &operator/=(const ll &x)
  144.     {
  145.         ll r = 0ll;
  146.         for (int i = (int)a.size() - 1; ~i; --i)
  147.         {
  148.             r = r * BASE + a[i];
  149.             a[i] = r / x;
  150.             r %= x;
  151.         }
  152.         fix();
  153.         return *this;
  154.     }
  155.     Bignum operator+(const Bignum &s)
  156.     {
  157.         Bignum c;
  158.         c.a.resize(a.size());
  159.         copy(a.begin(), a.end(), c.a.begin());
  160.         c += s;
  161.         return c;
  162.     }
  163.     Bignum operator-(const Bignum &s)
  164.     {
  165.         Bignum c;
  166.         c.a.resize(a.size());
  167.         copy(a.begin(), a.end(), c.a.begin());
  168.         c -= s;
  169.         return c;
  170.     }
  171.     Bignum operator*(const Bignum &s)
  172.     {
  173.         Bignum c;
  174.         c.a.resize(a.size());
  175.         copy(a.begin(), a.end(), c.a.begin());
  176.         c *= s;
  177.         return c;
  178.     }
  179.     Bignum operator/(const ll &x)
  180.     {
  181.         Bignum c;
  182.         c.a.resize(a.size());
  183.         copy(a.begin(), a.end(), c.a.begin());
  184.         c /= x;
  185.         return c;
  186.     }
  187.     ll operator%(const ll &x)
  188.     {
  189.         ll ans(0);
  190.         for (int i = a.size() - 1; ~i; --i)
  191.             ans = (ans * BASE + a[i]) % x;
  192.         return ans;
  193.     }
  194.     int com(const Bignum &s) const
  195.     {
  196.         if (a.size() < s.a.size())
  197.             return 1;
  198.         if (a.size() > s.a.size())
  199.             return 2;
  200.         for (int i = a.size() - 1; ~i; --i)
  201.             if (a[i] > s.a[i])
  202.                 return 2;
  203.             else if (a[i] < s.a[i])
  204.                 return 1;
  205.         return 3;
  206.     }
  207.     bool operator<(const Bignum &s) const
  208.     {
  209.         return com(s) == 1;
  210.     }
  211.     bool operator>(const Bignum &s) const
  212.     {
  213.         return com(s) == 2;
  214.     }
  215.     bool operator==(const Bignum &s) const
  216.     {
  217.         return com(s) == 3;
  218.     }
  219.     bool operator<=(const Bignum &s) const
  220.     {
  221.         return com(s) != 2;
  222.     }
  223.     bool operator>=(const Bignum &s) const
  224.     {
  225.         return com(s) != 1;
  226.     }
  227.     void read()
  228.     {
  229.         string s;
  230.         cin >> s;
  231.         Convert(s);
  232.     }
  233.     void print()
  234.     {
  235.         int i = a.size() - 1;
  236.         cout << a[i];
  237.         for (--i; ~i; --i)
  238.             cout << setw(gd) << setfill('0') << a[i];
  239.     }
  240.     friend istream &operator>>(istream &in, Bignum &x)
  241.     {
  242.         string s;
  243.         in >> s;
  244.         x.Convert(s);
  245.         return in;
  246.     }
  247.     friend ostream &operator<<(ostream &out, const Bignum &x)
  248.     {
  249.         int i = x.a.size() - 1;
  250.         out << x.a[i];
  251.         for (--i; ~i; --i)
  252.             out << setw(gd) << setfill('0') << x.a[i];
  253.         return out;
  254.     }
  255. };
Add Comment
Please, Sign In to add comment