#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;
}

使用提示

运算

先定义 _uint128a,b,m;\_uint128 a , b , m;

1.加法:a+ba + b

2.减法:aba - b

3.乘法:abmultiply(a,b)a * b 或 multiply(a , b)

4.除法:a/ba / b

5.取模:a%ba \% b

6.乘方:a(b)a(b)fast_pow_int(a,b,m)fast\_pow\_int(a , b , m)fast_pow_ll(a,b,m)fast\_pow\_ll(a , b , m)

7.内存优化快速幂:fast_pow(a,b,m)fast\_pow(a , b , m)

8.开整方:sqarture_integer(a)sqarture\_integer(a)

输入输出

代码里 ioio 方式必须一致,不然运算处理器会爆

1.原装:cin>>a;cin >> a;cout<<a;cout << a;

2.超快读(比手写快读快):read(a);read(a);write(a);write(a);

TIPS

1.千万不要定义在全局!!!

2.cincincoutcout 不要readreadwritewrite 一起用!!!

3.能自己写换行就不要用 fendlfendlflendlflendl!!!

(自取 , 请勿在ste库中加入任何无关东西)

2 条评论

  • @ 2026-7-9 20:49:22

    加法:O(2)

    减法:O(2)

    乘法:O(128) (常数最优)

    除法:O(n) (不太准确,常数比乘法更大)

    乘方:O(n) 和 O(log n)

    开方:O(n) (常数级,具体取决于迭代精度)

    • @ 2026-7-9 20:45:45

      因为是大数运算,时间复杂度可能会比普通ll的运算高几个常数级,但总体都是采用最优的算法,暂无发现更快的运算算法

      • 1