結果
| 問題 |
No.858 わり算
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2019-08-09 21:32:24 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 2,000 ms |
| コード長 | 30,086 bytes |
| コンパイル時間 | 10,789 ms |
| コンパイル使用メモリ | 282,532 KB |
| 実行使用メモリ | 6,820 KB |
| 最終ジャッジ日時 | 2025-01-07 14:48:57 |
| 合計ジャッジ時間 | 10,369 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 9 |
ソースコード
#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;
}