Skip to content

io.hpp

SECTIONUtility INCLUDEnoya/io.hpp

启用快速标准输入输出,并精确读写有符号 128 位整数。

Complexity: Time: O(1) setup and O(d) for a d-digit conversion. Space: O(d) for the returned decimal string.

AC 记录:aplusb, many_aplusb, many_aplusb_128bit

跳到代码 · GitHub ↗

Implementation

当前头文件,省略 include guard;依赖见 #include

/// @complexity Time: O(1) setup and O(d) for a d-digit conversion.
/// Space: O(d) for the returned decimal string.

#include <algorithm>
#include <cassert>
#include <iostream>
#include <string>
#include <string_view>

namespace noya {

/// @brief Fast standard-stream setup and exact signed 128-bit decimal I/O.
/// Disabling C/C++ stream synchronization removes redundant buffering. Decimal
/// parsing accumulates an unsigned magnitude so the minimum signed value is
/// representable; formatting performs the inverse repeated division without
/// ever negating that minimum value in signed arithmetic.
inline void fast_io() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
}

inline __int128 parse_int128(std::string_view tok) {
  assert(!tok.empty());
  bool neg = tok.front() == '-';
  bool sgn = tok.front() == '+';
  std::size_t pos = neg || sgn;
  assert(pos < tok.size());
  unsigned __int128 mag = 0;
  for (; pos < tok.size(); ++pos) {
    char d = tok[pos];
    assert('0' <= d && d <= '9');
    mag = mag * 10 + unsigned(d - '0');
  }
  constexpr unsigned __int128 sg0 = static_cast<unsigned __int128>(1) << 127;
  assert(mag <= (neg ? sg0 : sg0 - 1));
  if (!neg) {
    return static_cast<__int128>(mag);
  }
  if (mag == sg0) {
    return -static_cast<__int128>(sg0 - 1) - 1;
  }
  return -static_cast<__int128>(mag);
}

inline std::string to_string_int128(__int128 val) {
  bool neg = val < 0;
  unsigned __int128 mag = neg ? static_cast<unsigned __int128>(-(val + 1)) + 1
                              : static_cast<unsigned __int128>(val);
  std::string res;
  do {
    res.push_back(char('0' + mag % 10));
    mag /= 10;
  } while (mag != 0);
  if (neg) {
    res.push_back('-');
  }
  std::reverse(res.begin(), res.end());
  return res;
}

} // namespace noya
#ifndef NOYA_IO_HPP
#define NOYA_IO_HPP 1

/// @complexity Time: O(1) setup and O(d) for a d-digit conversion.
/// Space: O(d) for the returned decimal string.

#include <algorithm>
#include <cassert>
#include <iostream>
#include <string>
#include <string_view>

namespace noya {

/// @brief Fast standard-stream setup and exact signed 128-bit decimal I/O.
/// Disabling C/C++ stream synchronization removes redundant buffering. Decimal
/// parsing accumulates an unsigned magnitude so the minimum signed value is
/// representable; formatting performs the inverse repeated division without
/// ever negating that minimum value in signed arithmetic.
inline void fast_io() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
}

inline __int128 parse_int128(std::string_view tok) {
  assert(!tok.empty());
  bool neg = tok.front() == '-';
  bool sgn = tok.front() == '+';
  std::size_t pos = neg || sgn;
  assert(pos < tok.size());
  unsigned __int128 mag = 0;
  for (; pos < tok.size(); ++pos) {
    char d = tok[pos];
    assert('0' <= d && d <= '9');
    mag = mag * 10 + unsigned(d - '0');
  }
  constexpr unsigned __int128 sg0 = static_cast<unsigned __int128>(1) << 127;
  assert(mag <= (neg ? sg0 : sg0 - 1));
  if (!neg) {
    return static_cast<__int128>(mag);
  }
  if (mag == sg0) {
    return -static_cast<__int128>(sg0 - 1) - 1;
  }
  return -static_cast<__int128>(mag);
}

inline std::string to_string_int128(__int128 val) {
  bool neg = val < 0;
  unsigned __int128 mag = neg ? static_cast<unsigned __int128>(-(val + 1)) + 1
                              : static_cast<unsigned __int128>(val);
  std::string res;
  do {
    res.push_back(char('0' + mag % 10));
    mag /= 10;
  } while (mag != 0);
  if (neg) {
    res.push_back('-');
  }
  std::reverse(res.begin(), res.end());
  return res;
}

} // namespace noya

#endif // NOYA_IO_HPP
#include <algorithm>
#include <cassert>
#include <iostream>
#include <string>
#include <string_view>

/// @complexity Time: O(1) setup and O(d) for a d-digit conversion.
/// Space: O(d) for the returned decimal string.

namespace noya {

/// @brief Fast standard-stream setup and exact signed 128-bit decimal I/O.
/// Disabling C/C++ stream synchronization removes redundant buffering. Decimal
/// parsing accumulates an unsigned magnitude so the minimum signed value is
/// representable; formatting performs the inverse repeated division without
/// ever negating that minimum value in signed arithmetic.
inline void fast_io() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
}

inline __int128 parse_int128(std::string_view tok) {
  assert(!tok.empty());
  bool neg = tok.front() == '-';
  bool sgn = tok.front() == '+';
  std::size_t pos = neg || sgn;
  assert(pos < tok.size());
  unsigned __int128 mag = 0;
  for (; pos < tok.size(); ++pos) {
    char d = tok[pos];
    assert('0' <= d && d <= '9');
    mag = mag * 10 + unsigned(d - '0');
  }
  constexpr unsigned __int128 sg0 = static_cast<unsigned __int128>(1) << 127;
  assert(mag <= (neg ? sg0 : sg0 - 1));
  if (!neg) {
    return static_cast<__int128>(mag);
  }
  if (mag == sg0) {
    return -static_cast<__int128>(sg0 - 1) - 1;
  }
  return -static_cast<__int128>(mag);
}

inline std::string to_string_int128(__int128 val) {
  bool neg = val < 0;
  unsigned __int128 mag = neg ? static_cast<unsigned __int128>(-(val + 1)) + 1
                              : static_cast<unsigned __int128>(val);
  std::string res;
  do {
    res.push_back(char('0' + mag % 10));
    mag /= 10;
  } while (mag != 0);
  if (neg) {
    res.push_back('-');
  }
  std::reverse(res.begin(), res.end());
  return res;
}

} // namespace noya