結果

問題 No.858 わり算
ユーザー PachicobuePachicobue
提出日時 2019-08-09 21:32:24
言語 C++17
(gcc 13.2.0 + boost 1.83.0)
結果
AC  
実行時間 2 ms / 2,000 ms
コード長 30,086 bytes
コンパイル時間 4,101 ms
コンパイル使用メモリ 224,856 KB
実行使用メモリ 4,352 KB
最終ジャッジ日時 2023-10-12 08:34:59
合計ジャッジ時間 4,450 ms
ジャッジサーバーID
(参考情報)
judge12 / judge15
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,348 KB
testcase_01 AC 2 ms
4,352 KB
testcase_02 AC 2 ms
4,348 KB
testcase_03 AC 1 ms
4,348 KB
testcase_04 AC 2 ms
4,348 KB
testcase_05 AC 1 ms
4,348 KB
testcase_06 AC 2 ms
4,352 KB
testcase_07 AC 1 ms
4,348 KB
testcase_08 AC 2 ms
4,352 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
#pragma GCC diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#define NDEBUG
#define SHOW(...) static_cast<void>(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 <typename T>
T read()
{
    T v;
    return std::cin >> v, v;
}
template <typename T>
std::vector<T> readVec(const std::size_t l)
{
    std::vector<T> 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 <typename T>
constexpr T INF = std::numeric_limits<T>::max() / 4;
template <typename F>
constexpr F PI = static_cast<F>(3.1415926535897932385);
std::mt19937 mt{std::random_device{}()};
template <typename T>
bool chmin(T& a, const T& b) { return (a > b ? a = b, true : false); }
template <typename T>
bool chmax(T& a, const T& b) { return (a < b ? a = b, true : false); }
template <typename T>
std::vector<T> Vec(const std::size_t n, T v) { return std::vector<T>(n, v); }
template <class... Args>
auto Vec(const std::size_t n, Args... args) { return std::vector<decltype(Vec(args...))>(n, Vec(args...)); }
template <typename T>
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<unsigned long long>(u);
    return v = (v & 0x5555555555555555ULL) + (v >> 1 & 0x5555555555555555ULL), v = (v & 0x3333333333333333ULL) + (v >> 2 & 0x3333333333333333ULL), v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL, static_cast<T>(v * 0x0101010101010101ULL >> 56 & 0x7f);
#endif
}
template <typename T>
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<unsigned long long>(u);
    return v = static_cast<unsigned long long>(v), v |= (v >> 1), v |= (v >> 2), v |= (v >> 4), v |= (v >> 8), v |= (v >> 16), v |= (v >> 32), popCount(v);
#endif
}
template <typename T>
constexpr T clog(const T v) { return v == 0 ? T(0) : log2p1(v - 1); }
template <typename T>
constexpr T msbp1(const T v) { return log2p1(v); }
template <typename T>
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 <typename T>
constexpr bool ispow2(const T v) { return popCount(v) == 1; }
template <typename T>
constexpr T ceil2(const T v) { return v == 0 ? T(1) : T(1) << log2p1(v - 1); }
template <typename T>
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 <typename T>
constexpr std::pair<T, T> extgcd(const T a, const T b)
{
    if (b == 0) { return std::pair<T, T>{1, 0}; }
    const auto p = extgcd(b, a % b);
    return {p.second, p.first - p.second * (a / b)};
}
template <typename T>
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 <uint mod>
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<ll>(x.v), static_cast<ll>(mod))}; }

public:
    ModInt() : v{0} {}
    ModInt(const ll val) : v{norm(uint(val % static_cast<ll>(mod) + static_cast<ll>(mod)))} {}
    ModInt(const ModInt& n) : v{n()} {}
    explicit operator bool() const { return v != 0; }
    bool operator!() const { return not static_cast<bool>(*this); }
    ModInt& operator=(const ModInt& m) { return v = m(), (*this); }
    ModInt& operator=(const ll val) { return v = norm(uint(val % static_cast<ll>(mod) + static_cast<ll>(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<uint>(static_cast<ll>(m1.v) * static_cast<ll>(m2.v) % static_cast<ll>(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<ll>(m.v) + val}; }
    friend ModInt operator-(const ModInt& m, const ll val) { return ModInt{static_cast<ll>(m.v) - val}; }
    friend ModInt operator*(const ModInt& m, const ll val) { return ModInt{static_cast<ll>(m.v) * (val % static_cast<ll>(mod))}; }
    friend ModInt operator/(const ModInt& m, const ll val) { return ModInt{static_cast<ll>(m.v) * inv(val)}; }
    friend ModInt operator+(const ll val, const ModInt& m) { return ModInt{static_cast<ll>(m.v) + val}; }
    friend ModInt operator-(const ll val, const ModInt& m) { return ModInt{-static_cast<ll>(m.v) + val}; }
    friend ModInt operator*(const ll val, const ModInt& m) { return ModInt{static_cast<ll>(m.v) * (val % static_cast<ll>(mod))}; }
    friend ModInt operator/(const ll val, const ModInt& m) { return ModInt{val * inv(static_cast<ll>(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<uint>(static_cast<ll>(mod) + val % static_cast<ll>(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<uint>(static_cast<ll>(mod) + val % static_cast<ll>(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<ModInt> invVec(const std::size_t N)
    {
        std::vector<ModInt> 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 <typename F>
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 <typename F = double>
class FFT
{
private:
    static constexpr std::size_t L = 30;

public:
    FFT() = delete;
    static void fft(std::vector<Complex<F>>& a, const std::size_t lg, const bool rev)
    {
        static std::vector<Complex<F>> 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<F>(PI<F> * F(2 * i) / F(N)); }
        }
        std::vector<Complex<F>> 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<F> 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 <typename T = ll, typename I = int>
    static std::vector<T> simpleConvolute(const std::vector<I>& a, const std::vector<I>& b)
    {
        const std::size_t need = a.size() + b.size() - 1, lg = clog(need), N = 1UL << lg;
        std::vector<Complex<F>> A(N), B(N);
        for (std::size_t i = 0; i < a.size(); i++) { A[i] = Complex<F>{F(a[i]), 0}; }
        for (std::size_t i = 0; i < b.size(); i++) { B[i] = Complex<F>{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<T> ans(need);
        for (std::size_t i = 0; i < need; i++) { ans[i] = T(std::round(A[i].x)); }
        return ans;
    }
    template <typename T = ll, std::size_t K = 2, typename I = int>
    static std::vector<T> convolute(const std::vector<I>& a, const std::vector<I>& 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<Complex<F>> 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<F>{});
            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<F>{tmp[j].x + tmp[k].x, tmp[j].y - tmp[k].y}, B[i][j] = Complex<F>{tmp[j].y + tmp[k].y, -tmp[j].x + tmp[k].x};
            }
        }
        std::vector<Complex<F>> 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<F>(0, 1);
                    }
                }
            }
        }
        for (std::size_t i = 0; i < K; i++) { fft(Z[i], lg, true); }
        std::vector<T> 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 <uint mod, std::size_t K = 2>
    static std::vector<ModInt<mod>> convolute(const std::vector<ModInt<mod>>& a, const std::vector<ModInt<mod>>& 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<Complex<F>> 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<F>{});
            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<F>{tmp[j].x + tmp[k].x, tmp[j].y - tmp[k].y}, B[i][j] = Complex<F>{tmp[j].y + tmp[k].y, -tmp[j].x + tmp[k].x};
            }
        }
        std::vector<Complex<F>> 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<F>(0, 1);
                    }
                }
            }
        }
        for (std::size_t i = 0; i < K; i++) { fft(Z[i], lg, true); }
        std::vector<ModInt<mod>> ans(need);
        ModInt<mod> 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 <std::size_t D = 7, std::size_t K = 2, typename T = long long>
class BigInt
{
    static constexpr T TEN(const std::size_t n) { return n == 0 ? static_cast<T>(1) : TEN(n - 1) * static_cast<T>(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<T>& 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<bool>(*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<T> 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<T> 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<T, K, T>(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<T> 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<T> 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<T> 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<BigInt, T> 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<T> 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, T>{BigInt{s, ans}, m.sign ? rem : -rem};
    }
    friend std::pair<BigInt, BigInt> 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<T> 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, BigInt>{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<T>(10), ans++) {}
        return ans;
    }
    friend int absComp(const BigInt& m, const BigInt& n)  // m<n:-1  m=n:0  m>n: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<T> 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<BigInt<>>(), B = read<BigInt<>>();
    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;
}
0