io.hpp¶
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.
Verified by aplusb, many_aplusb, many_aplusb_128bit.
启用快速标准输入输出,并精确读写有符号 128 位整数。
Implementation¶
#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 token) {
assert(!token.empty());
bool negative = token.front() == '-';
bool positive = token.front() == '+';
std::size_t position = negative || positive;
assert(position < token.size());
unsigned __int128 magnitude = 0;
for (; position < token.size(); ++position) {
char digit = token[position];
assert('0' <= digit && digit <= '9');
magnitude = magnitude * 10 + unsigned(digit - '0');
}
constexpr unsigned __int128 sign_bit =
static_cast<unsigned __int128>(1) << 127;
assert(magnitude <= (negative ? sign_bit : sign_bit - 1));
if (!negative) {
return static_cast<__int128>(magnitude);
}
if (magnitude == sign_bit) {
return -static_cast<__int128>(sign_bit - 1) - 1;
}
return -static_cast<__int128>(magnitude);
}
inline std::string to_string_int128(__int128 value) {
bool negative = value < 0;
unsigned __int128 magnitude = negative
? static_cast<unsigned __int128>(-(value + 1)) + 1
: static_cast<unsigned __int128>(value);
std::string result;
do {
result.push_back(char('0' + magnitude % 10));
magnitude /= 10;
} while (magnitude != 0);
if (negative) {
result.push_back('-');
}
std::reverse(result.begin(), result.end());
return result;
}
} // 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 token) {
assert(!token.empty());
bool negative = token.front() == '-';
bool positive = token.front() == '+';
std::size_t position = negative || positive;
assert(position < token.size());
unsigned __int128 magnitude = 0;
for (; position < token.size(); ++position) {
char digit = token[position];
assert('0' <= digit && digit <= '9');
magnitude = magnitude * 10 + unsigned(digit - '0');
}
constexpr unsigned __int128 sign_bit =
static_cast<unsigned __int128>(1) << 127;
assert(magnitude <= (negative ? sign_bit : sign_bit - 1));
if (!negative) {
return static_cast<__int128>(magnitude);
}
if (magnitude == sign_bit) {
return -static_cast<__int128>(sign_bit - 1) - 1;
}
return -static_cast<__int128>(magnitude);
}
inline std::string to_string_int128(__int128 value) {
bool negative = value < 0;
unsigned __int128 magnitude = negative
? static_cast<unsigned __int128>(-(value + 1)) + 1
: static_cast<unsigned __int128>(value);
std::string result;
do {
result.push_back(char('0' + magnitude % 10));
magnitude /= 10;
} while (magnitude != 0);
if (negative) {
result.push_back('-');
}
std::reverse(result.begin(), result.end());
return result;
}
} // namespace noya