#include #pragma GCC diagnostic ignored "-Wsign-compare" #pragma GCC diagnostic ignored "-Wsign-conversion" #define NDEBUG #define SHOW(...) static_cast(0) //!===========================================================!// //! dP dP dP !// //! 88 88 88 !// //! 88aaaaa88a .d8888b. .d8888b. .d888b88 .d8888b. 88d888b. !// //! 88 88 88ooood8 88' '88 88' '88 88ooood8 88' '88 !// //! 88 88 88. ... 88. .88 88. .88 88. ... 88 !// //! dP dP '88888P' '88888P8 '88888P8 '88888P' dP !// //!===========================================================!// template T read() { T v; return std::cin >> v, v; } template std::vector readVec(const std::size_t l) { std::vector v(l); for (auto& e : v) { std::cin >> e; } return v; } using ld = long double; using uint = unsigned int; using ll = long long; using ull = unsigned long long; constexpr unsigned int MOD = 1000000007; template constexpr T INF = std::numeric_limits::max() / 4; template constexpr F PI = static_cast(3.1415926535897932385); std::mt19937 mt{std::random_device{}()}; template bool chmin(T& a, const T& b) { return (a > b ? a = b, true : false); } template bool chmax(T& a, const T& b) { return (a < b ? a = b, true : false); } template std::vector Vec(const std::size_t n, T v) { return std::vector(n, v); } template auto Vec(const std::size_t n, Args... args) { return std::vector(n, Vec(args...)); } template constexpr T popCount(const T u) { #ifdef __has_builtin return u == 0 ? T(0) : (T)__builtin_popcountll(u); #else unsigned long long v = static_cast(u); return v = (v & 0x5555555555555555ULL) + (v >> 1 & 0x5555555555555555ULL), v = (v & 0x3333333333333333ULL) + (v >> 2 & 0x3333333333333333ULL), v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL, static_cast(v * 0x0101010101010101ULL >> 56 & 0x7f); #endif } template constexpr T log2p1(const T u) { #ifdef __has_builtin return u == 0 ? T(0) : T(64 - __builtin_clzll(u)); #else unsigned long long v = static_cast(u); return v = static_cast(v), v |= (v >> 1), v |= (v >> 2), v |= (v >> 4), v |= (v >> 8), v |= (v >> 16), v |= (v >> 32), popCount(v); #endif } template constexpr T clog(const T v) { return v == 0 ? T(0) : log2p1(v - 1); } template constexpr T msbp1(const T v) { return log2p1(v); } template constexpr T lsbp1(const T v) { #ifdef __has_builtin return __builtin_ffsll(v); #else return v == 0 ? T(0) : popCount((v & (-v)) - T(1)) + T(1); #endif } template constexpr bool ispow2(const T v) { return popCount(v) == 1; } template constexpr T ceil2(const T v) { return v == 0 ? T(1) : T(1) << log2p1(v - 1); } template constexpr T floor2(const T v) { return v == 0 ? T(0) : T(1) << (log2p1(v) - 1); } //!===============================================================!// //! 88888888b dP .88888. a88888b. 888888ba !// //! 88 88 d8' '88 d8' '88 88 '8b !// //! a88aaaa dP. .dP d8888P 88 88 88 88 !// //! 88 '8bd8' 88 88 YP88 88 88 88 !// //! 88 .d88b. 88 Y8. .88 Y8. .88 88 .8P !// //! 88888888P dP' 'dP dP '88888' Y88888P' 8888888P !// //!===============================================================!// template constexpr std::pair extgcd(const T a, const T b) { if (b == 0) { return std::pair{1, 0}; } const auto p = extgcd(b, a % b); return {p.second, p.first - p.second * (a / b)}; } template constexpr T inverse(const T a, const T mod) { return (mod + extgcd((mod + a % mod) % mod, mod).first % mod) % mod; } //!========================================================!// //! 8888ba.88ba dP dP dP !// //! 88 '8b '8b 88 88 88 !// //! 88 88 88 .d8888b. .d888b88 88 88d888b. d8888P !// //! 88 88 88 88' '88 88' '88 88 88' '88 88 !// //! 88 88 88 88. .88 88. .88 88 88 88 88 !// //! dP dP dP '88888P' '88888P8 dP dP dP dP !// //!========================================================!// template class ModInt { private: uint v; static uint norm(const uint& x) { return x < mod ? x : x - mod; } static ModInt make(const uint& x) { ModInt m; return m.v = x, m; } static ModInt power(ModInt x, ll n) { ModInt ans = 1; for (; n; n >>= 1, x *= x) { if (n & 1) { ans *= x; } } return ans; } static ModInt inv(const ModInt& x) { return ModInt{inverse(static_cast(x.v), static_cast(mod))}; } public: ModInt() : v{0} {} ModInt(const ll val) : v{norm(uint(val % static_cast(mod) + static_cast(mod)))} {} ModInt(const ModInt& n) : v{n()} {} explicit operator bool() const { return v != 0; } bool operator!() const { return not static_cast(*this); } ModInt& operator=(const ModInt& m) { return v = m(), (*this); } ModInt& operator=(const ll val) { return v = norm(uint(val % static_cast(mod) + static_cast(mod))), (*this); } friend ModInt operator+(const ModInt& m) { return m; } friend ModInt operator-(const ModInt& m) { return make(norm(mod - m.v)); } friend ModInt operator+(const ModInt& m1, const ModInt& m2) { return make(norm(m1.v + m2.v)); } friend ModInt operator-(const ModInt& m1, const ModInt& m2) { return make(norm(m1.v + mod - m2.v)); } friend ModInt operator*(const ModInt& m1, const ModInt& m2) { return make(static_cast(static_cast(m1.v) * static_cast(m2.v) % static_cast(mod))); } friend ModInt operator/(const ModInt& m1, const ModInt& m2) { return m1 * inv(m2.v); } friend ModInt operator+(const ModInt& m, const ll val) { return ModInt{static_cast(m.v) + val}; } friend ModInt operator-(const ModInt& m, const ll val) { return ModInt{static_cast(m.v) - val}; } friend ModInt operator*(const ModInt& m, const ll val) { return ModInt{static_cast(m.v) * (val % static_cast(mod))}; } friend ModInt operator/(const ModInt& m, const ll val) { return ModInt{static_cast(m.v) * inv(val)}; } friend ModInt operator+(const ll val, const ModInt& m) { return ModInt{static_cast(m.v) + val}; } friend ModInt operator-(const ll val, const ModInt& m) { return ModInt{-static_cast(m.v) + val}; } friend ModInt operator*(const ll val, const ModInt& m) { return ModInt{static_cast(m.v) * (val % static_cast(mod))}; } friend ModInt operator/(const ll val, const ModInt& m) { return ModInt{val * inv(static_cast(m.v))}; } friend ModInt& operator+=(ModInt& m1, const ModInt& m2) { return m1 = m1 + m2; } friend ModInt& operator-=(ModInt& m1, const ModInt& m2) { return m1 = m1 - m2; } friend ModInt& operator*=(ModInt& m1, const ModInt& m2) { return m1 = m1 * m2; } friend ModInt& operator/=(ModInt& m1, const ModInt& m2) { return m1 = m1 / m2; } friend ModInt& operator+=(ModInt& m, const ll val) { return m = m + val; } friend ModInt& operator-=(ModInt& m, const ll val) { return m = m - val; } friend ModInt& operator*=(ModInt& m, const ll val) { return m = m * val; } friend ModInt& operator/=(ModInt& m, const ll val) { return m = m / val; } friend ModInt operator^(const ModInt& m, const ll n) { return power(m.v, n); } friend ModInt& operator^=(ModInt& m, const ll n) { return m = m ^ n; } friend bool operator==(const ModInt& m1, const ModInt& m2) { return m1.v == m2.v; } friend bool operator!=(const ModInt& m1, const ModInt& m2) { return not(m1 == m2); } friend bool operator==(const ModInt& m, const ll val) { return m.v == norm(static_cast(static_cast(mod) + val % static_cast(mod))); } friend bool operator!=(const ModInt& m, const ll val) { return not(m == val); } friend bool operator==(const ll val, const ModInt& m) { return m.v == norm(static_cast(static_cast(mod) + val % static_cast(mod))); } friend bool operator!=(const ll val, const ModInt& m) { return not(m == val); } friend std::istream& operator>>(std::istream& is, ModInt& m) { uint v; return is >> v, m = v, is; } friend std::ostream& operator<<(std::ostream& os, const ModInt& m) { return os << m(); } static std::vector invVec(const std::size_t N) { std::vector ans(N + 1, 1); for (std::size_t i = 2; i <= N; i++) { ans[i] = -ans[mod % i] * (mod / i); } return ans; } uint operator()() const { return v; } }; template struct Complex { F x, y; Complex() : x(0), y(0) {} Complex(const F& s) : x(std::cos(s)), y(std::sin(s)) {} Complex(const F x, const F y) : x(x), y(y) {} Complex operator-() const { return Complex(-x, -y); } Complex operator+(const Complex& c) const { return Complex{x + c.x, y + c.y}; } Complex operator-(const Complex& c) const { return Complex{x - c.x, y - c.y}; } Complex operator*(const Complex& c) const { return Complex{x * c.x - y * c.y, x * c.y + y * c.x}; } Complex operator*(const F& r) const { return Complex{x * r, y * r}; } Complex& operator+=(const Complex& c) { return this->x += c.x, this->y += c.y, *this; } Complex& operator-=(const Complex& c) { return this->x -= c.x, this->y -= c.y, *this; } Complex& operator*=(const Complex& c) { return *this = *this * c; } Complex& operator*=(const F& r) { return this->x *= r, this->y *= r, *this; } Complex conj() const { return Complex{x, -y}; } }; //!==================================!// //! 88888888b 88888888b d888888P !// //! 88 88 88 !// //! a88aaaa a88aaaa 88 !// //! 88 88 88 !// //! 88 88 88 !// //! dP dP dP !// //!==================================!// template class FFT { private: static constexpr std::size_t L = 30; public: FFT() = delete; static void fft(std::vector>& a, const std::size_t lg, const bool rev) { static std::vector> root[L]; const std::size_t N = a.size(); assert((1UL << lg) == N); if (root[lg].empty()) { root[lg].reserve(N), root[lg].resize(N); for (std::size_t i = 0; i < N; i++) { root[lg][i] = Complex(PI * F(2 * i) / F(N)); } } std::vector> tmp(N); for (std::size_t w = (N >> 1); w > 0; w >>= 1) { for (std::size_t y = 0; y < (N >> 1); y += w) { const Complex r = rev ? root[lg][y].conj() : root[lg][y]; for (std::size_t x = 0; x < w; x++) { const auto u = a[y << 1 | x], v = a[y << 1 | x | w] * r; tmp[y | x] = u + v, tmp[y | x | (N >> 1)] = u - v; } } std::swap(tmp, a); } } template static std::vector simpleConvolute(const std::vector& a, const std::vector& b) { const std::size_t need = a.size() + b.size() - 1, lg = clog(need), N = 1UL << lg; std::vector> A(N), B(N); for (std::size_t i = 0; i < a.size(); i++) { A[i] = Complex{F(a[i]), 0}; } for (std::size_t i = 0; i < b.size(); i++) { B[i] = Complex{F(b[i]), 0}; } fft(A, lg, false), fft(B, lg, false); for (std::size_t i = 0; i < N; i++) { A[i] *= B[i] * ((F)1 / (F)N); } fft(A, lg, true); std::vector ans(need); for (std::size_t i = 0; i < need; i++) { ans[i] = T(std::round(A[i].x)); } return ans; } template static std::vector convolute(const std::vector& a, const std::vector& b) { constexpr std::size_t V = 30; constexpr std::size_t S = (V + K - 1) / K; const std::size_t need = a.size() + b.size() - 1, lg = clog(need), N = 1UL << lg; std::vector> A[K], B[K], tmp(N); for (std::size_t i = 0; i < K; i++) { A[i].reserve(N), A[i].resize(N), B[i].reserve(N), B[i].resize(N); std::fill(tmp.begin() + std::min(a.size(), b.size()), tmp.end(), Complex{}); for (std::size_t j = 0; j < a.size(); j++) { tmp[j].x = F((a[j] >> (S * i)) & ((1 << S) - 1)); } for (std::size_t j = 0; j < b.size(); j++) { tmp[j].y = F((b[j] >> (S * i)) & ((1 << S) - 1)); } fft(tmp, lg, false); for (std::size_t j = 0; j < N; j++) { tmp[j] *= F(0.5); } for (std::size_t j = 0; j < N; j++) { const std::size_t k = j == 0 ? 0UL : N - j; A[i][j] = Complex{tmp[j].x + tmp[k].x, tmp[j].y - tmp[k].y}, B[i][j] = Complex{tmp[j].y + tmp[k].y, -tmp[j].x + tmp[k].x}; } } std::vector> Z[K]; for (std::size_t i = 0; i < K; i++) { Z[i].reserve(N), Z[i].resize(N); } for (std::size_t a = 0; a < K; a++) { for (std::size_t b = 0; b < K; b++) { for (std::size_t i = 0; i < N; i++) { if (a + b < K) { Z[a + b][i] += A[a][i] * B[b][i]; } else { Z[a + b - K][i] += A[a][i] * B[b][i] * Complex(0, 1); } } } } for (std::size_t i = 0; i < K; i++) { fft(Z[i], lg, true); } std::vector ans(need); T base = 1; for (std::size_t k = 0; k < 2 * K - 1; k++, base *= (1LL << S)) { for (std::size_t i = 0; i < need; i++) { if (k < K) { ans[i] += base * T(std::round(Z[k][i].x / F(N))); } else { ans[i] += base * T(std::round(Z[k - K][i].y / F(N))); } } } return ans; } template static std::vector> convolute(const std::vector>& a, const std::vector>& b) { constexpr std::size_t V = 30; constexpr std::size_t S = (V + K - 1) / K; const std::size_t need = a.size() + b.size() - 1, lg = clog(need), N = 1UL << lg; std::vector> A[K], B[K], tmp(N); for (std::size_t i = 0; i < K; i++) { A[i].reserve(N), A[i].resize(N), B[i].reserve(N), B[i].resize(N); std::fill(tmp.begin() + std::min(a.size(), b.size()), tmp.end(), Complex{}); for (std::size_t j = 0; j < a.size(); j++) { tmp[j].x = F((a[j]() >> (S * i)) & ((1 << S) - 1)); } for (std::size_t j = 0; j < b.size(); j++) { tmp[j].y = F((b[j]() >> (S * i)) & ((1 << S) - 1)); } fft(tmp, lg, false); for (std::size_t j = 0; j < N; j++) { tmp[j] *= F(0.5); } for (std::size_t j = 0; j < N; j++) { const std::size_t k = j == 0 ? 0UL : N - j; A[i][j] = Complex{tmp[j].x + tmp[k].x, tmp[j].y - tmp[k].y}, B[i][j] = Complex{tmp[j].y + tmp[k].y, -tmp[j].x + tmp[k].x}; } } std::vector> Z[K]; for (std::size_t i = 0; i < K; i++) { Z[i].reserve(N), Z[i].resize(N); } for (std::size_t a = 0; a < K; a++) { for (std::size_t b = 0; b < K; b++) { for (std::size_t i = 0; i < N; i++) { if (a + b < K) { Z[a + b][i] += A[a][i] * B[b][i]; } else { Z[a + b - K][i] += A[a][i] * B[b][i] * Complex(0, 1); } } } } for (std::size_t i = 0; i < K; i++) { fft(Z[i], lg, true); } std::vector> ans(need); ModInt base = 1; for (std::size_t k = 0; k < 2 * K - 1; k++, base *= (1LL << S)) { for (std::size_t i = 0; i < need; i++) { if (k < K) { ans[i] += int((base * ll(std::round(Z[k][i].x / F(N))))()); } else { ans[i] += int((base * ll(std::round(Z[k - K][i].y / F(N))))()); } } } return ans; } }; //!=============================================!// //! 888888ba oo dP dP !// //! 88 '8b 88 88 !// //! a88aaaa8P' dP .d8888b. 88 88d888b. d8888P !// //! 88 '8b. 88 88' '88 88 88' '88 88 !// //! 88 .88 88 88. .88 88 88 88 88 !// //! 88888888P dP '8888P88 dP dP dP dP !// //! .88 !// //! d8888P !// //!=============================================!// template class BigInt { static constexpr T TEN(const std::size_t n) { return n == 0 ? static_cast(1) : TEN(n - 1) * static_cast(10); } public: static constexpr T B = TEN(D); BigInt() {} BigInt(const T x) : sign(x >= 0), d(x == 0 ? 0 : 1, x < 0 ? -x : x) { normalize(); } BigInt(const bool sign, const std::vector& d) : sign(sign), d(d) { normalize(); } BigInt(const BigInt& n) : sign(n.sign), d(n.d) {} BigInt(const std::string& S) { assert(not S.empty()); sign = S[0] != '-'; for (std::size_t i = 0; i < S.size(); i += D) { const std::size_t R = S.size() - i, L = (sign ? (R >= D ? R - D : 0) : (R > D ? R - D : 1)); if (R > L) { d.push_back((T)std::stoll(S.substr(L, R - L))); } } } friend BigInt operator+(const BigInt& m) { return m; } friend BigInt operator-(const BigInt& m) { return BigInt{not m.sign, m.d}; } explicit operator bool() const { return not d.empty(); } bool operator!() const { return not static_cast(*this); } friend BigInt operator+(const BigInt& m, const BigInt& n) { if (m.sign == n.sign) { std::size_t L = std::max(m.d.size(), n.d.size()); std::vector v(L, 0); for (std::size_t i = 0; i < m.d.size(); i++) { v[i] += m.d[i]; } for (std::size_t i = 0; i < n.d.size(); i++) { v[i] += n.d[i]; } return BigInt{m.sign, v}; } else { std::size_t L = std::max(m.d.size(), n.d.size()); std::vector v(L, 0); if (absComp(m, n) == -1) { for (std::size_t i = 0; i < m.d.size(); i++) { v[i] -= m.d[i]; } for (std::size_t i = 0; i < n.d.size(); i++) { v[i] += n.d[i]; } return BigInt{n.sign, v}; } else { for (std::size_t i = 0; i < m.d.size(); i++) { v[i] += m.d[i]; } for (std::size_t i = 0; i < n.d.size(); i++) { v[i] -= n.d[i]; } return BigInt{m.sign, v}; } } } friend BigInt operator-(const BigInt& m, const BigInt& n) { return m + (-n); } friend BigInt operator*(const BigInt& m, const BigInt& n) { return BigInt{not(m.sign ^ n.sign), FFT<>::convolute(m.d, n.d)}; } friend BigInt operator/(const BigInt& m, const BigInt& n) { return div(m, n).first; } friend BigInt operator%(const BigInt& m, const BigInt& n) { return div(m, n).second; } friend BigInt operator^(const BigInt& m, const long long n) { return n == 0 ? BigInt{1} : n % 2 == 1 ? (m ^ (n - 1)) * m : (m * m) ^ (n / 2); } friend int comp(const BigInt& m, const BigInt& n) { if (m.sign != n.sign) { return m.sign ? 1 : -1; } else { return m.sign ? absComp(m, n) : -absComp(m, n); } } friend bool operator<(const BigInt& m, const BigInt& n) { return comp(m, n) == -1; } friend bool operator>(const BigInt& m, const BigInt& n) { return comp(m, n) == 1; } friend bool operator==(const BigInt& m, const BigInt& n) { return comp(m, n) == 0; } friend bool operator!=(const BigInt& m, const BigInt& n) { return not(m == n); } friend bool operator<=(const BigInt& m, const BigInt& n) { return not(m > n); } friend bool operator>=(const BigInt& m, const BigInt& n) { return not(m < n); } friend BigInt operator<<(const BigInt& m, const std::size_t n) // *(B^n) { std::vector ans(m.d.size() + n, 0); for (std::size_t i = 0; i < m.d.size(); i++) { ans[i + n] = m.d[i]; } return BigInt{m.sign, ans}; } friend BigInt operator>>(const BigInt& m, const std::size_t n) // /(B^n) { if (m.d.size() <= n) { return 0; } std::vector ans(m.d.size() - n, 0); for (std::size_t i = 0; i < m.d.size() - n; i++) { ans[i] = m.d[i + n]; } return BigInt{m.sign, ans}; } BigInt& operator=(const BigInt& n) { return sign = n.sign, d = n.d, *this; } BigInt& operator=(const T n) { return *this = BigInt{n}; } friend BigInt& operator+=(BigInt& m, const BigInt& n) { return m = m + n; } friend BigInt& operator-=(BigInt& m, const BigInt& n) { return m = m - n; } friend BigInt& operator*=(BigInt& m, const BigInt& n) { return m = m * n; } friend BigInt& operator/=(BigInt& m, const BigInt& n) { return m = m / n; } friend BigInt& operator%=(BigInt& m, const BigInt& n) { return m = m % n; } friend BigInt& operator^=(BigInt m, const long long n) { return m = m ^ n; } friend BigInt& operator<<=(BigInt& m, const std::size_t n) { return m = m << n; } friend BigInt& operator>>=(BigInt& m, const std::size_t n) { return m = m >> n; } friend BigInt operator+(const BigInt& m, const T n) { return m + BigInt{n}; } friend BigInt operator-(const BigInt& m, const T n) { return m - BigInt{n}; } friend BigInt operator*(const BigInt& m, const T n) { return m * BigInt{n}; } friend BigInt operator/(const BigInt& m, const T n) { return m / BigInt{n}; } friend BigInt operator%(const BigInt& m, const T n) { return m % BigInt{n}; } friend bool operator<(const BigInt& m, const T n) { return comp(m, BigInt{n}) == -1; } friend bool operator>(const BigInt& m, const T n) { return comp(m, BigInt{n}) == 1; } friend bool operator==(const BigInt& m, const T n) { return comp(m, BigInt{n}) == 0; } friend bool operator!=(const BigInt& m, const T n) { return not(m == n); } friend bool operator<=(const BigInt& m, const T n) { return not(m > n); } friend bool operator>=(const BigInt& m, const T n) { return not(m < n); } friend BigInt& operator+=(const BigInt& m, const T n) { return m += BigInt{n}; } friend BigInt& operator-=(const BigInt& m, const T n) { return m -= BigInt{n}; } friend BigInt& operator*=(const BigInt& m, const T n) { return m *= BigInt{n}; } friend BigInt& operator/=(const BigInt& m, const T n) { return m /= BigInt{n}; } friend BigInt& operator%=(const BigInt& m, const T n) { return m %= BigInt{n}; } friend BigInt operator+(const T m, const BigInt& n) { return BigInt{m} + n; } friend BigInt operator-(const T m, const BigInt& n) { return BigInt{m} - n; } friend BigInt operator*(const T m, const BigInt& n) { return BigInt{m} * n; } friend BigInt operator/(const T m, const BigInt& n) { return BigInt{m} / n; } friend BigInt operator%(const T m, const BigInt& n) { return BigInt{m} % n; } friend bool operator<(const T m, const BigInt& n) { return comp(BigInt{m}, n) == -1; } friend bool operator>(const T m, const BigInt& n) { return comp(BigInt{m}, n) == 1; } friend bool operator==(const T m, const BigInt& n) { return comp(BigInt{m}, n) == 0; } friend bool operator!=(const T m, const BigInt& n) { return not(m == n); } friend bool operator<=(const T m, const BigInt& n) { return not(m > n); } friend bool operator>=(const T m, const BigInt& n) { return not(m < n); } BigInt& operator++() { return *this += BigInt{1}; } BigInt operator++(int) { return std::exchange(*this, *this + BigInt{1}); } BigInt& operator--() { return *this -= BigInt{1}; } BigInt operator--(int) { return std::exchange(*this, *this - BigInt{1}); } friend BigInt smallMul(const BigInt& m, T n) { const bool s = n < 0 ? not m.sign : m.sign; n = n < 0 ? -n : n; assert(n < B); std::vector ans(m.d.size()); for (std::size_t i = 0; i < m.d.size(); i++) { ans[i] = m.d[i] * n; } return BigInt{s, ans}; } friend std::pair smallDiv(const BigInt& m, T n) { assert(n != 0); const bool s = n >= 0 ? m.sign : not m.sign; n = n < 0 ? -n : n; assert(n < B); std::vector ans(m.d.size()); T rem = 0; for (std::size_t i = 0; i < m.d.size(); i++) { const std::size_t ind = m.d.size() - i - 1; ans[ind] = (m.d[ind] + rem * B) / n, rem = (m.d[ind] + rem * B) - ans[ind] * n; } return std::pair{BigInt{s, ans}, m.sign ? rem : -rem}; } friend std::pair div(BigInt m, BigInt n) { assert(not n.d.empty()); if (absComp(m, n) == -1) { return {0, m}; } const bool ms = m.sign, ns = n.sign; m.sign = n.sign = true; const std::size_t S = m.d.size() - n.d.size(); std::vector sho(S + 1); for (std::size_t i = 0; i <= S; i++) { const std::size_t ind = S - i; const auto L = m >> ind; T inf = -1, sup = B; while (sup - inf > 1) { const T mid = (sup + inf) >> 1; (absComp(L, smallMul(n, mid)) == -1 ? sup : inf) = mid; } sho[ind] = inf, m -= (smallMul(n, inf) << ind); } return m.sign = ms, std::pair{BigInt{not(ms ^ ns), sho}, m}; } friend std::istream& operator>>(std::istream& is, BigInt& n) { std::string S; is >> S; return n = BigInt{S}, is; } friend std::ostream& operator<<(std::ostream& os, const BigInt& n) { if (n.d.empty()) { return os << '0'; } if (n.sign == false) { os << '-'; } const std::size_t N = n.d.size(); for (std::size_t i = 0; i < N; i++) { if (i == 0) { os << n.d[N - i - 1]; } else { std::size_t NZ = 0; for (T U = 1; n.d[N - i - 1] >= U; NZ++, U *= T(10)) {} for (std::size_t i = 0; i + NZ < D; i++) { os << '0'; } if (n.d[N - i - 1] != 0LL) { os << n.d[N - i - 1]; } } } return os; } friend std::size_t log10p1(const BigInt& m) { if (m.d.empty()) { return 0; } assert(m.sign); return (m.d.size() - 1) * D + log10p1(m.d.back()); } friend BigInt abs(const BigInt& m) { auto ans = m; return ans.sign = true, ans; } long long to_ll() const { long long ans = 0, base = 1; for (std::size_t i = 0; i < d.size(); i++, base *= B) { ans += base * d[i]; } return sign ? ans : -ans; } std::string to_string() const { if (d.empty()) { return "0"; } std::string ans; if (sign == false) { ans.push_back('-'); } const std::size_t N = d.size(); for (std::size_t i = 0; i < N; i++) { if (i == 0) { ans += std::to_string(d[N - i - 1]); } else { std::size_t NZ = 0; for (T U = 1; d[N - i - 1] >= U; NZ++, U *= T(10)) {} for (std::size_t i = 0; i + NZ < D; i++) { ans.push_back('0'); } if (d[N - i - 1] != 0LL) { ans += std::to_string(d[N - i - 1]); } } } return ans; } private: static std::size_t log10p1(const T n) { std::size_t ans = 0; for (T base = 1; base <= n; base *= static_cast(10), ans++) {} return ans; } friend int absComp(const BigInt& m, const BigInt& n) // mn:1 { if (m.d.size() != n.d.size()) { return m.d.size() < n.d.size() ? -1 : 1; } else { for (std::size_t i = 0; i < m.d.size(); i++) { const auto M = m.d[m.d.size() - i - 1], N = n.d[n.d.size() - i - 1]; if (M != N) { return M < N ? -1 : 1; } } } return 0; } void normalize() { for (std::size_t i = 0; i < d.size(); i++) { if (d[i] >= B) { if (i + 1 == d.size()) { d.push_back(d[i] / B); } else { d[i + 1] += d[i] / B; } d[i] %= B; } else if (d[i] < 0) { assert(i + 1 != d.size()); while (d[i] < 0) { d[i + 1]--, d[i] += B; } } } for (; not d.empty() and d.back() == 0; d.pop_back()) {} } bool sign = true; std::vector d; }; //!=====================================!// //! 8888ba.88ba oo !// //! 88 '8b '8b !// //! 88 88 88 .d8888b. dP 88d888b. !// //! 88 88 88 88' '88 88 88' '88 !// //! 88 88 88 88. .88 88 88 88 !// //! dP dP dP '88888P8 dP dP dP !// //!=====================================!// int main() { auto A = read>(), B = read>(); for (int i = 0; i < 50; i++) { A *= BigInt<>(10); } auto S = (A / B).to_string(); while (S.size() <= 50) { S = "0" + S; } const int L = S.size(); for (int i = 0; i < L; i++) { std::cout << S[i]; if (i == L - 51) { std::cout << '.'; } } std::cout << std::endl; return 0; }