- 编程
手写_uint128(以后会持续更新)
- @ 2026-7-9 20:29:56
#include <bits/stdc++.h>
using namespace std;
vector<bool> a;
namespace ste {
#if __cplusplus > 201103L
const int OUT_BUF_SIZE = 100000;
char out_buf[OUT_BUF_SIZE];
int out_p = 0;
inline void flush() {
if (out_p > 0) {
fwrite(out_buf, 1, out_p, stdout);
out_p = 0;
}
}
struct Flusher {
~Flusher() { flush(); }
} global_flusher;
inline void pc(char c) {
if (out_p == OUT_BUF_SIZE) flush();
out_buf[out_p++] = c;
}
class _uint128 {
private:
uint64_t high;
uint64_t low;
static void div_mod(const _uint128& dividend, const _uint128& divisor, _uint128& quotient, _uint128& remainder) {
if (divisor.high == 0 && divisor.low == 0)
throw std::runtime_error("Division by zero!");
quotient = _uint128(0, 0);
remainder = _uint128(0, 0);
for (int i = 127; i >= 0; --i) {
remainder = remainder.shiftLeftOne();
uint64_t bit = 0;
if (i >= 64)
bit = (dividend.high >> (i - 64)) & 1ULL;
else
bit = (dividend.low >> i) & 1ULL;
remainder.low |= bit;
if (remainder >= divisor) {
remainder = remainder - divisor;
if (i >= 64)
quotient.high |= (1ULL << (i - 64));
else
quotient.low |= (1ULL << i);
}
}
}
static const int BUF_SIZE = 100000;
public:
_uint128() : high(0), low(0) {}
_uint128(uint64_t l) : high(0), low(l) {}
_uint128(uint64_t h, uint64_t l) : high(h), low(l) {}
explicit operator bool() const {
return this->high != 0 || this->low != 0;
}
explicit operator uint64_t() const {
return this->low;
}
explicit operator uint32_t() const {
return static_cast<uint32_t>(this->low);
}
_uint128 operator+(const _uint128& other) const {
_uint128 res;
res.low = this->low + other.low;
uint64_t carry = (res.low < this->low) ? 1 : 0;
res.high = this->high + other.high + carry;
return res;
}
bool operator==(const _uint128& other) const {
return this->high == other.high && this->low == other.low;
}
bool operator!=(const _uint128& other) const {
return !(*this == other);
}
bool operator<(const _uint128& other) const {
if (this->high < other.high) return true;
if (this->high == other.high && this->low < other.low) return true;
return false;
}
bool operator>(const _uint128& other) const {
if (this->high > other.high) return true;
if (this->high == other.high && this->low > other.low) return true;
return false;
}
bool operator<=(const _uint128& other) const {
if (this->high < other.high) return true;
if (this->high == other.high && this->low <= other.low) return true;
return false;
}
bool operator>=(const _uint128& other) const {
if (this->high > other.high) return true;
if (this->high == other.high && this->low >= other.low) return true;
return false;
}
static inline char gc() {
static char buf[BUF_SIZE];
static char *p1 = buf, *p2 = buf;
if (p1 == p2) {
p2 = (p1 = buf) + fread(buf, 1, BUF_SIZE, stdin);
if (p1 == p2) return EOF;
}
return *p1++;
}
_uint128 shiftLeftOne() const {
_uint128 res;
res.high = (this->high << 1) | (this->low >> 63);
res.low = this->low << 1;
return res;
}
_uint128 shiftRightOne() const {
_uint128 res;
res.low = (this->low >> 1) | (this->high << 63);
res.high = this->high >> 1;
return res;
}
_uint128 operator<<(int k) const {
if (k == 0) return *this;
if (k >= 64)
return _uint128(this->low << (k - 64), 0);
else
return _uint128((this->high << k) | (this->low >> (64 - k)), this->low << k);
}
_uint128 operator>>(int k) const {
if (k == 0) return *this;
if (k >= 64)
return _uint128(0, this->high >> (k - 64));
else
return _uint128(this->high >> k, (this->low >> k) | (this->high << (64 - k)));
}
_uint128 operator*(const _uint128& other) const {
_uint128 result(0, 0);
_uint128 a = *this;
_uint128 b = other;
for (int i = 0; i < 128; ++i) {
if (b.low & 1)
result = result + a;
a = a.shiftLeftOne();
b = b.shiftRightOne();
if (b.high == 0 && b.low == 0)
break;
}
return result;
}
_uint128 operator-(const _uint128& other) const {
_uint128 res;
res.low = this->low - other.low;
uint64_t borrow = (this->low < other.low) ? 1 : 0;
res.high = this->high - other.high - borrow;
return res;
}
_uint128 operator/(const _uint128& other) const {
_uint128 quotient, remainder;
div_mod(*this, other, quotient, remainder);
return quotient;
}
_uint128 operator%(const _uint128& other) const {
_uint128 quotient, remainder;
div_mod(*this, other, quotient, remainder);
return remainder;
}
_uint128 operator()(const uint32_t other) const {
_uint128 res = 1 , comp = *this;
for (uint32_t bycount = 0; bycount < other; ++ bycount)
res *= comp;
return res;
}
_uint128& operator++() {
this->low++;
if (this->low == 0)
this->high++;
return *this;
}
_uint128 operator++(int) {
_uint128 temp = *this;
++(*this);
return temp;
}
_uint128& operator--() {
if (this->low == 0)
this->high--;
this->low--;
return *this;
}
_uint128 operator--(int) {
_uint128 temp = *this;
--(*this);
return temp;
}
_uint128 operator&(const _uint128& other) const {
return _uint128(this->high & other.high, this->low & other.low);
}
_uint128 operator|(const _uint128& other) const {
return _uint128(this->high | other.high, this->low | other.low);
}
_uint128 operator^(const _uint128& other) const {
return _uint128(this->high ^ other.high, this->low ^ other.low);
}
_uint128 operator~() const {
return _uint128(~this->high, ~this->low);
}
bool operator!() const {
return this->high == 0 && this->low == 0;
}
_uint128& operator+=(const _uint128& other) { *this = *this + other; return *this; }
_uint128& operator-=(const _uint128& other) { *this = *this - other; return *this; }
_uint128& operator*=(const _uint128& other) { *this = *this * other; return *this; }
_uint128& operator/=(const _uint128& other) { *this = *this / other; return *this; }
_uint128& operator%=(const _uint128& other) { *this = *this % other; return *this; }
_uint128& operator&=(const _uint128& other) { *this = *this & other; return *this; }
_uint128& operator|=(const _uint128& other) { *this = *this | other; return *this; }
_uint128& operator^=(const _uint128& other) { *this = *this ^ other; return *this; }
_uint128& operator<<=(int k) { *this = *this << k; return *this; }
_uint128& operator>>=(int k) { *this = *this >> k; return *this; }
_uint128 operator+() const {
return *this;
}
_uint128 operator-() const {
return ~(*this) + _uint128(1);
}
static inline _uint128 multiply(const _uint128& a, const _uint128& b) {
uint64_t high_cross = (a.high * b.low) + (a.low * b.high);
uint64_t a32 = a.low & 0xFFFFFFFF;
uint64_t a64 = a.low >> 32;
uint64_t b32 = b.low & 0xFFFFFFFF;
uint64_t b64 = b.low >> 32;
uint64_t res32 = a32 * b32;
uint64_t res64 = (res32 >> 32) + a64 * b32;
uint64_t res96 = res64 >> 32;
res64 = (res64 & 0xFFFFFFFF) + a32 * b64;
res96 += res64 >> 32;
uint64_t final_low = (res64 << 32) | (res32 & 0xFFFFFFFF);
uint64_t final_high = res96 + (a64 * b64);
return _uint128(final_high + high_cross, final_low);
}
static inline _uint128 fast_pow_int (_uint128 a , uint32_t b , _uint128 m) {
_uint128 res = 1;
while (b) {
if (b & 1)
res = (res * (a % m)) % m;
a = (a % m) * (a % m);
b >>= 1;
}
return res % m;
}
static inline _uint128 fast_pow_ll (_uint128 a , uint64_t b , _uint128 m) {
_uint128 res = 1;
while (b) {
if (b & 1)
res = (res * (a % m)) % m;
a = (a % m) * (a % m);
b >>= 1;
}
return res % m;
}
//优化 ############################################################
template <typename _Tp>
static inline _uint128 fast_pow (_uint128 a , _Tp b , _uint128 m) {
_uint128 res = 1;
while (b) {
if (b & 1)
res = (res * (a % m)) % m;
a = (a % m) * (a % m);
b >>= 1;
}
return res % m;
}
//_Tp 内存优化 ####################################################
/* (deleted)
template<typename _Tp>
inline _GLIBCXX_CONSTEXPR
typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
double>::__type
sqrt(_Tp __x)
{ return __builtin_sqrt(__x); }
*/
static inline _uint128 sqarture_integer (_uint128 x) {
_uint128 res = x;
for (uint32_t spi = 1; spi < 32; spi ++)
res = (res + x / res) >> 1;
return res;
}
friend std::istream& operator>>(std::istream& in, _uint128& num) {
std::string s;
in >> s;
num = _uint128(0, 0);
for (char c : s) {
if (c < '0' || c > '9') break;
_uint128 digit(0, c - '0');
num = (num << 3) + (num << 1) + digit;
}
return in;
}
friend std::ostream& operator<<(std::ostream& out, const _uint128& num) {
if (num.high == 0 && num.low == 0)
return out << "0";
uint64_t E18_val = 1000000000000000000ULL;
_uint128 E18(0, E18_val);
_uint128 temp = num;
std::vector<uint64_t> chunks;
while (temp.high > 0 || temp.low > 0) {
_uint128 q, r;
div_mod(temp, E18, q, r);
chunks.push_back(r.low);
temp = q;
}
for (int i = chunks.size() - 1; i >= 0; --i) {
if (i == (int)chunks.size() - 1)
out << chunks[i];
else {
std::string s = std::to_string(chunks[i]);
out << std::string(18 - s.length(), '0') << s;
}
}
return out;
}
static inline void read(_uint128 &num) {
num = _uint128(0, 0);
char c = gc();
while (c < '0' || c > '9')
c = gc();
while (c >= '0' && c <= '9') {
_uint128 digit(0, c - '0');
num = (num << 3) + (num << 1) + digit;
c = gc();
}
}
static inline void write(const _uint128& num) {
if (num.high == 0 && num.low == 0) {
pc('0');
return;
}
uint64_t E18_val = 1000000000000000000ULL;
_uint128 E18(0, E18_val);
_uint128 temp = num;
uint64_t chunks[3];
int chunk_cnt = 0;
while (temp.high > 0 || temp.low > 0) {
_uint128 q, r;
div_mod(temp, E18, q, r);
chunks[chunk_cnt++] = r.low;
temp = q;
}
for (int i = chunk_cnt - 1; i >= 0; --i) {
uint64_t val = chunks[i];
if (i == chunk_cnt - 1) {
char stack[25];
int top = 0;
while (val > 0) {
stack[top++] = (char)(val % 10 + '0');
val /= 10;
}
while (top > 0) pc(stack[--top]);
} else {
char stack[18];
for (int j = 0; j < 18; ++j) {
stack[j] = (char)(val % 10 + '0');
val /= 10;
}
for (int j = 17; j >= 0; --j) pc(stack[j]);
}
}
}
static inline void writeln(const _uint128& num) {
write(num);
pc('\n');
}
};
#endif
//os
class FastOstream;
inline FastOstream& endl(FastOstream& os);
inline FastOstream& flush_endl(FastOstream& os);
class FastOstream {
public:
FastOstream& operator<<(const _uint128& num) {
_uint128::write(num);
return *this;
}
FastOstream& operator<<(char c) {
pc(c);
return *this;
}
FastOstream& operator<<(const char* str) {
while (*str) pc(*str++);
return *this;
}
FastOstream& operator<<(FastOstream& (*manipulator)(FastOstream&)) {
return manipulator(*this);
}
};
FastOstream fout;
inline FastOstream& fendl(FastOstream& os) {
pc('\n');
return os;
}
inline FastOstream& flendl(FastOstream& os) {
pc('\n');
flush();
return os;
}
}
using namespace ste;
int main () {
_uint128 a;
int b;
cin >> a >> b;
cout << ste::_uint128::sqarture_integer(a) << ' ';//展示猪肝
cout << ste::_uint128::fast_pow(a , b , 100);//装13
return 0;
}
使用提示
运算
先定义
1.加法:
2.减法:
3.乘法:
4.除法:
5.取模:
6.乘方: 或 及
7.内存优化快速幂:
8.开整方:
输入输出
代码里 方式必须一致,不然运算处理器会爆
1.原装: 和
2.超快读(比手写快读快): 和
TIPS
1.千万不要定义在全局!!!
2. 和 不要和 和 一起用!!!
3.能自己写换行就不要用 和 !!!
(自取 , 请勿在ste库中加入任何无关东西)