Skip to content

Commit 610d1a5

Browse files
chore: update minified library versions
1 parent 949b115 commit 610d1a5

File tree

3 files changed

+6
-4
lines changed

3 files changed

+6
-4
lines changed

cp-algo/min/number_theory/discrete_log.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
#define CP_ALGO_NUMBER_THEORY_DISCRETE_LOG_HPP
33
#include "euler.hpp"
44
#include <optional>
5-
namespace cp_algo::math{template<typename _Int>std::optional<_Int>discrete_log(_Int b,_Int c,_Int m,_Int a=1){if(std::abs(a-c)%m==0){return 0;}if(std::gcd(a,m)!=std::gcd(int64_t(a)*b,int64_t(m))){auto res=discrete_log(b,c,m,_Int(int64_t(a)*b%m));return res?std::optional(*res+1):res;}using Int=std::make_signed_t<_Int>;using base=dynamic_modint<Int>;return base::with_mod(m,[&]()->std::optional<_Int>{int sqrtmod=std::max(1,(int)std::sqrt(m)/2);std::unordered_map<_Int,int>small;base cur=a;for(int i=0;i<sqrtmod;i++){small[cur.getr()]=i;cur*=b;}base step=bpow(base(b),sqrtmod);cur=1;for(ptrdiff_t k=0;k<m;k+=sqrtmod){auto it=small.find((base(c)*cur).getr());if(it!=end(small)){auto cand=base::with_mod(period(base(b)),[&](){return base(it->second-k).getr();});if(base(a)*bpow(base(b),cand)==base(c)){return cand;}else{return std::nullopt;}}cur*=step;}return std::nullopt;});}}
5+
namespace cp_algo::math{template<typename _Int>std::optional<_Int>discrete_log(_Int b,_Int c,_Int m,_Int a=1){if(std::abs(a-c)%m==0){return 0;}if(std::gcd(a,m)!=std::gcd(int64_t(a)*b,int64_t(m))){auto res=discrete_log(b,c,m,_Int(int64_t(a)*b%m));return res?std::optional(*res+1):res;}using Int=std::make_signed_t<_Int>;using base=dynamic_modint<Int>;return base::with_mod(m,[&]()->std::optional<_Int>{int sqrtmod=std::max(1,(int)std::sqrt(m)/2);big_map<_Int,int>small;base cur=a;for(int i=0;i<sqrtmod;i++){small[cur.getr()]=i;cur*=b;}base step=bpow(base(b),sqrtmod);cur=1;for(ptrdiff_t k=0;k<m;k+=sqrtmod){auto it=small.find((base(c)*cur).getr());if(it!=end(small)){auto cand=base::with_mod(period(base(b)),[&](){return base(it->second-k).getr();});if(base(a)*bpow(base(b),cand)==base(c)){return cand;}else{return std::nullopt;}}cur*=step;}return std::nullopt;});}}
66
#endif
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#ifndef CP_ALGO_MATH_FACTORIZE_HPP
22
#define CP_ALGO_MATH_FACTORIZE_HPP
33
#include "primality.hpp"
4+
#include "../util/big_alloc.hpp"
45
#include "../random/rng.hpp"
56
#include <generator>
6-
namespace cp_algo::math{template<typename _Int>auto proper_divisor(_Int m){using Int=std::make_signed_t<_Int>;using base=dynamic_modint<Int>;return m%2==0?2:base::with_mod(m,[&](){base t=random::rng();auto f=[&](auto x){return x*x+t;};base x=0,y=0;base g=1;while(g==1){for(int i=0;i<64;i++){x=f(x);y=f(f(y));if(x==y)[[unlikely]]{t=random::rng();x=y=0;}else{base t=g*(x-y);g=t==0?g:t;}}g=std::gcd(g.getr(),m);}return g.getr();});}template<typename Int>std::generator<Int>factorize(Int m){if(is_prime(m)){co_yield m;}else if(m>1){auto g=proper_divisor(m);co_yield std::ranges::elements_of(factorize(g));co_yield std::ranges::elements_of(factorize(m/g));}}template<typename Int>std::generator<Int>divisors_sqrt(Int m){for(Int i=1;i*i<=m;i++){if(m%i==0){co_yield i;if(i*i!=m){co_yield m/i;}}}}}
7+
namespace cp_algo::math{template<typename _Int>auto proper_divisor(_Int m){using Int=std::make_signed_t<_Int>;using base=dynamic_modint<Int>;return m%2==0?2:base::with_mod(m,[&](){base t=random::rng();auto f=[&](auto x){return x*x+t;};base x=0,y=0;base g=1;while(g==1){for(int i=0;i<64;i++){x=f(x);y=f(f(y));if(x==y)[[unlikely]]{t=random::rng();x=y=0;}else{base t=g*(x-y);g=t==0?g:t;}}g=std::gcd(g.getr(),m);}return g.getr();});}template<typename Int>big_generator<Int>factorize(Int m){if(is_prime(m)){co_yield m;}else if(m>1){auto g=proper_divisor(m);co_yield std::ranges::elements_of(factorize(g));co_yield std::ranges::elements_of(factorize(m/g));}}template<typename Int>big_generator<Int>divisors_sqrt(Int m){for(Int i=1;i*i<=m;i++){if(m%i==0){co_yield i;if(i*i!=m){co_yield m/i;}}}}}
78
#endif

cp-algo/min/util/big_alloc.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,20 @@
88
#include <string>
99
#include <cstddef>
1010
#include <iostream>
11+
#include <generator>
1112
#if defined(__linux__) || defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
1213
# define CP_ALGO_USE_MMAP 1
1314
# include <sys/mman.h>
1415
#else
1516
# define CP_ALGO_USE_MMAP 0
1617
#endif
17-
namespace cp_algo{template<typename T,std::size_t Align=32>class big_alloc{static_assert(Align>=alignof(void*),"Align must be at least pointer-size");static_assert(std::popcount(Align)==1,"Align must be a power of two");public:using value_type=T;template<class U>struct rebind{using other=big_alloc<U,Align>;};constexpr bool operator==(const big_alloc&)const=default;constexpr bool operator!=(const big_alloc&)const=default;big_alloc()noexcept=default;template<typename U,std::size_t A>big_alloc(const big_alloc<U,A>&)noexcept{}[[nodiscard]]T*allocate(std::size_t n){std::size_t padded=round_up(n*sizeof(T));std::size_t align=std::max<std::size_t>(alignof(T),Align);
18+
namespace cp_algo{template<typename T,size_t Align=32>class big_alloc{static_assert(Align>=alignof(void*),"Align must be at least pointer-size");static_assert(std::popcount(Align)==1,"Align must be a power of two");public:using value_type=T;template<class U>struct rebind{using other=big_alloc<U,Align>;};constexpr bool operator==(const big_alloc&)const=default;constexpr bool operator!=(const big_alloc&)const=default;big_alloc()noexcept=default;template<typename U,std::size_t A>big_alloc(const big_alloc<U,A>&)noexcept{}[[nodiscard]]T*allocate(std::size_t n){std::size_t padded=round_up(n*sizeof(T));std::size_t align=std::max<std::size_t>(alignof(T),Align);
1819
#if CP_ALGO_USE_MMAP
1920
if(padded>=MEGABYTE){void*raw=mmap(nullptr,padded,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0);madvise(raw,padded,MADV_HUGEPAGE);madvise(raw,padded,MADV_POPULATE_WRITE);return static_cast<T*>(raw);}
2021
#endif
2122
return static_cast<T*>(::operator new(padded,std::align_val_t(align)));}void deallocate(T*p,std::size_t n)noexcept{if(!p)return;std::size_t padded=round_up(n*sizeof(T));std::size_t align=std::max<std::size_t>(alignof(T),Align);
2223
#if CP_ALGO_USE_MMAP
2324
if(padded>=MEGABYTE){munmap(p,padded);return;}
2425
#endif
25-
::operator delete(p,padded,std::align_val_t(align));}private:static constexpr std::size_t MEGABYTE=1<<20;static constexpr std::size_t round_up(std::size_t x)noexcept{return(x+Align-1)/Align*Align;}};template<typename T>using big_vector=std::vector<T,big_alloc<T>>;template<typename T>using big_basic_string=std::basic_string<T,std::char_traits<T>,big_alloc<T>>;template<typename T>using big_deque=std::deque<T,big_alloc<T>>;template<typename Key,typename Value,typename Compare=std::less<Key>>using big_map=std::map<Key,Value,Compare,big_alloc<std::pair<const Key,Value>>>;using big_string=big_basic_string<char>;template<typename T>using big_stack=std::stack<T,big_deque<T>>;template<typename T>using big_queue=std::queue<T,big_deque<T>>;template<typename T>using big_priority_queue=std::priority_queue<T,big_vector<T>>;}
26+
::operator delete(p,padded,std::align_val_t(align));}private:static constexpr std::size_t MEGABYTE=1<<20;static constexpr std::size_t round_up(std::size_t x)noexcept{return(x+Align-1)/Align*Align;}};template<typename T>using big_vector=std::vector<T,big_alloc<T>>;template<typename T>using big_basic_string=std::basic_string<T,std::char_traits<T>,big_alloc<T>>;template<typename T>using big_deque=std::deque<T,big_alloc<T>>;template<typename Key,typename Value,typename Compare=std::less<Key>>using big_map=std::map<Key,Value,Compare,big_alloc<std::pair<const Key,Value>>>;using big_string=big_basic_string<char>;template<typename T>using big_stack=std::stack<T,big_deque<T>>;template<typename T>using big_queue=std::queue<T,big_deque<T>>;template<typename T>using big_priority_queue=std::priority_queue<T,big_vector<T>>;template<typename Ref,typename V=void>using big_generator=std::generator<Ref,V,big_alloc<std::byte>>;}namespace std::ranges{template<typename Ref,typename V>elements_of(cp_algo::big_generator<Ref,V>&&)->elements_of<cp_algo::big_generator<Ref,V>&&,cp_algo::big_alloc<std::byte>>;}
2627
#endif

0 commit comments

Comments
 (0)