Dang_Quan_10_Tin

Bignum

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