Skip to content

Commit 1ec2ba2

Browse files
chore: update minified library versions
1 parent 25faa7e commit 1ec2ba2

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

cp-algo/min/math/bigint.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef CP_ALGO_MATH_BIGINT_HPP
22
#define CP_ALGO_MATH_BIGINT_HPP
33
#include "../util/big_alloc.hpp"
4+
#include "../math/fft64.hpp"
45
#include <bits/stdc++.h>
5-
namespace cp_algo::math{enum base_v{x10=uint64_t(1e18),x16=uint64_t(0)};template<base_v base=x10>struct bigint{big_vector<uint64_t>digits;bool negative;bigint(){}bigint&normalize(){while(!empty(digits)&&digits.back()==0){digits.pop_back();}if(digits.empty()){negative=false;}return*this;}bigint&negate(){negative^=1;return*this;}bigint operator-(){return bigint(*this).negate();}bigint&operator-=(const bigint&other){if(negative!=other.negative){return(negate()+=other).negate().normalize();}digits.resize(std::max(size(digits),size(other.digits)));bool carry=false;auto d_ptr=std::assume_aligned<32>(digits.data());auto o_ptr=std::assume_aligned<32>(other.digits.data());size_t N=size(other.digits);size_t i=0;for(;i<N;i++){if constexpr(base==x10){d_ptr[i]-=o_ptr[i]+carry;carry=d_ptr[i]>=base;d_ptr[i]+=carry?uint64_t(base):0;}else if constexpr(base==x16){auto sub=o_ptr[i]+carry;auto new_carry=sub?(d_ptr[i]<sub):carry;d_ptr[i]-=sub;carry=new_carry;}else{static_assert(base==x10||base==x16,"Unsupported base");}}if(carry){N=size(digits);for(;i<N&&d_ptr[i]==0;i++){d_ptr[i]=base-1;}if(i<N){d_ptr[i]--;}else{d_ptr[0]--;for(i=0;i<N;i++){d_ptr[i]=base-d_ptr[i]-1;}negate();}}return normalize();}bigint&operator+=(const bigint&other){if(negative!=other.negative){return(negate()-=other).negate().normalize();}digits.resize(std::max(size(digits),size(other.digits)));bool carry=false;auto d_ptr=std::assume_aligned<32>(digits.data());auto o_ptr=std::assume_aligned<32>(other.digits.data());size_t N=size(other.digits);size_t i=0;for(;i<N;i++){if constexpr(base==x10){d_ptr[i]+=o_ptr[i]+carry;carry=d_ptr[i]>=base;d_ptr[i]-=carry?uint64_t(base):0;}else if constexpr(base==x16){auto add=o_ptr[i]+carry;auto new_carry=add?(d_ptr[i]>=-add):carry;d_ptr[i]+=add;carry=new_carry;}else{static_assert(base==x10||base==x16,"Unsupported base");}}if(carry){N=size(digits);for(;i<N&&d_ptr[i]==uint64_t(base)-1;i++){d_ptr[i]=0;}if(i<N){d_ptr[i]++;}else{digits.push_back(1);}}return*this;}bigint(std::span<char>s):negative(false){if(!empty(s)&&s[0]=='-'){negative=true;s=s.subspan(1);}size_t len=size(s);assert(len>0);constexpr auto digit_length=base==x10?18:base==x16?16:0;constexpr auto sub_base=base==x10?10:base==x16?16:0;size_t num_digits=(len+digit_length-1)/digit_length;digits.resize(num_digits);size_t i=len;for(size_t j=0;j<num_digits-1;j++){std::from_chars(s.data()+i-digit_length,s.data()+i,digits[j],sub_base);i-=digit_length;}std::from_chars(s.data(),s.data()+i,digits.back(),sub_base);normalize();}bigint operator+(const bigint&other)const{return bigint(*this)+=other;}bigint operator-(const bigint&other)const{return bigint(*this)-=other;}};template<base_v base>decltype(std::cin)&operator>>(decltype(std::cin)&in,cp_algo::math::bigint<base>&x){std::string s;in>>s;x={s};return in;}template<base_v base>decltype(std::cout)&operator<<(decltype(std::cout)&out,cp_algo::math::bigint<base>const&x){if(x.negative){out<<'-';}if(empty(x.digits)){return out<<'0';}constexpr auto digit_length=base==x10?18:base==x16?16:0;constexpr auto sub_base=base==x10?10:base==x16?16:0;char buf[20];auto[ptr,ec]=std::to_chars(buf,buf+sizeof(buf),x.digits.back(),sub_base);if constexpr(base==x16){std::ranges::transform(buf,buf,toupper);}out<<std::string_view(buf,ptr-buf);for(auto d:x.digits|std::views::reverse|std::views::drop(1)){auto[ptr,ec]=std::to_chars(buf,buf+sizeof(buf),d,sub_base);if constexpr(base==x16){std::ranges::transform(buf,buf,toupper);}auto len=ptr-buf;out<<std::string(digit_length-len,'0');out<<std::string_view(buf,len);}return out;}}
6+
namespace cp_algo::math{enum base_v{x10=uint64_t(1e18),x16=uint64_t(1ull<<60)};template<base_v base=x10>struct bigint{static constexpr uint16_t digit_length=base==x10?18:15;static constexpr uint16_t sub_base=base==x10?10:16;static constexpr uint32_t meta_base=base==x10?uint32_t(1e6):uint32_t(1<<20);big_vector<uint64_t>digits;bool negative;bigint(){}bigint&normalize(){while(!empty(digits)&&digits.back()==0){digits.pop_back();}if(digits.empty()){negative=false;}return*this;}bigint&negate(){negative^=1;return*this;}bigint operator-(){return bigint(*this).negate();}bigint&operator-=(const bigint&other){if(negative!=other.negative){return(negate()+=other).negate().normalize();}digits.resize(std::max(size(digits),size(other.digits)));bool carry=false;auto d_ptr=std::assume_aligned<32>(digits.data());auto o_ptr=std::assume_aligned<32>(other.digits.data());size_t N=size(other.digits);size_t i=0;for(;i<N;i++){d_ptr[i]-=o_ptr[i]+carry;carry=d_ptr[i]>=base;d_ptr[i]+=carry?uint64_t(base):0;}if(carry){N=size(digits);for(;i<N&&d_ptr[i]==0;i++){d_ptr[i]=base-1;}if(i<N){d_ptr[i]--;}else{d_ptr[0]--;for(i=0;i<N;i++){d_ptr[i]=base-d_ptr[i]-1;}negate();}}return normalize();}bigint&operator+=(const bigint&other){if(negative!=other.negative){return(negate()-=other).negate().normalize();}digits.resize(std::max(size(digits),size(other.digits)));bool carry=false;auto d_ptr=std::assume_aligned<32>(digits.data());auto o_ptr=std::assume_aligned<32>(other.digits.data());size_t N=size(other.digits);size_t i=0;for(;i<N;i++){d_ptr[i]+=o_ptr[i]+carry;carry=d_ptr[i]>=base;d_ptr[i]-=carry?uint64_t(base):0;}if(carry){N=size(digits);for(;i<N&&d_ptr[i]==uint64_t(base)-1;i++){d_ptr[i]=0;}if(i<N){d_ptr[i]++;}else{digits.push_back(1);}}return*this;}bigint(std::span<char>s):negative(false){if(!empty(s)&&s[0]=='-'){negative=true;s=s.subspan(1);}size_t len=size(s);assert(len>0);size_t num_digits=(len+digit_length-1)/digit_length;digits.resize(num_digits);size_t i=len;for(size_t j=0;j<num_digits-1;j++){std::from_chars(s.data()+i-digit_length,s.data()+i,digits[j],sub_base);i-=digit_length;}std::from_chars(s.data(),s.data()+i,digits.back(),sub_base);normalize();}bigint operator+(const bigint&other)const{return bigint(*this)+=other;}bigint operator-(const bigint&other)const{return bigint(*this)-=other;}void to_metabase(){auto N=ssize(digits);digits.resize(3*N);for(auto i=N-1;i>=0;i--){uint64_t val=digits[i];digits[3*i]=val%meta_base;val/=meta_base;digits[3*i+1]=val%meta_base;val/=meta_base;digits[3*i+2]=val;}}void from_metabase(){auto N=(ssize(digits)+2)/3;digits.resize(3*N);uint64_t carry=0;for(int i=0;i<N;i++){__uint128_t val=digits[3*i+2];val=val*meta_base+digits[3*i+1];val=val*meta_base+digits[3*i];val+=carry;digits[i]=uint64_t(val%base);carry=uint64_t(val/base);}digits.resize(N);while(carry){digits.push_back(carry%base);carry/=base;}}bigint&mul_inplace(auto&&other){size_t n=size(digits);size_t m=size(other.digits);negative^=other.negative;if(std::min(n,m)<128){big_vector<uint64_t>result(n+m);for(size_t i=0;i<n;i++){uint64_t carry=0;for(size_t j=0;j<m||carry;j++){__uint128_t cur=result[i+j]+carry;if(j<m){cur+=__uint128_t(digits[i])*other.digits[j];}result[i+j]=uint64_t(cur%base);carry=uint64_t(cur/base);}}digits=std::move(result);return normalize();}to_metabase();other.to_metabase();fft::conv64(digits,other.digits);from_metabase();return normalize();}bigint&operator*=(bigint const&other){return mul_inplace(bigint(other));}bigint operator*(const bigint&other)const{return bigint(*this).mul_inplace(bigint(other));}};template<base_v base>decltype(std::cin)&operator>>(decltype(std::cin)&in,cp_algo::math::bigint<base>&x){std::string s;in>>s;x={s};return in;}template<base_v base>decltype(std::cout)&operator<<(decltype(std::cout)&out,cp_algo::math::bigint<base>const&x){if(x.negative){out<<'-';}if(empty(x.digits)){return out<<'0';}char buf[20];auto[ptr,ec]=std::to_chars(buf,buf+sizeof(buf),x.digits.back(),bigint<base>::sub_base);if constexpr(base==x16){std::ranges::transform(buf,buf,toupper);}out<<std::string_view(buf,ptr-buf);for(auto d:x.digits|std::views::reverse|std::views::drop(1)){auto[ptr,ec]=std::to_chars(buf,buf+sizeof(buf),d,bigint<base>::sub_base);if constexpr(base==x16){std::ranges::transform(buf,buf,toupper);}auto len=ptr-buf;out<<std::string(bigint<base>::digit_length-len,'0');out<<std::string_view(buf,len);}return out;}}
67
#endif

0 commit comments

Comments
 (0)