Skip to content

Commit 6d184ce

Browse files
chore: update minified library versions
1 parent c6d9320 commit 6d184ce

File tree

4 files changed

+24
-3
lines changed

4 files changed

+24
-3
lines changed
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef CP_ALGO_STRUCTURES_BIT_ARRAY_HPP
22
#define CP_ALGO_STRUCTURES_BIT_ARRAY_HPP
33
#include "../util/bit.hpp"
4+
#include "../util/big_alloc.hpp"
45
#include <cassert>
5-
namespace cp_algo::structures{template<typename C>concept Resizable=requires(C&c,std::size_t n){c.resize(n);};template<class Cont>struct _bit_array{static constexpr size_t width=bit_width<uint64_t>;size_t words,n;alignas(32)Cont data;constexpr void resize(size_t N){n=N;words=(n+width-1)/width;if constexpr(Resizable<Cont>){data.resize(words);}else{assert(std::size(data)>=words);}}constexpr _bit_array():n(0),words(0),data(){}constexpr _bit_array(size_t N):data(){resize(N);}constexpr uint64_t&word(size_t x){return data[x];}constexpr uint64_t word(size_t x)const{return data[x];}constexpr void set_all(uint64_t val=-1){for(auto&w:data){w=val;}}constexpr void reset(){set_all(0);}constexpr void set(size_t x){word(x/width)|=1ULL<<(x%width);}constexpr void reset(size_t x){word(x/width)&=~(1ULL<<(x%width));}constexpr void flip(size_t x){word(x/width)^=1ULL<<(x%width);}constexpr bool test(size_t x)const{return(word(x/width)>>(x%width))&1;}constexpr bool operator[](size_t x)const{return test(x);}constexpr size_t size()const{return n;}};template<size_t N>struct bit_array:_bit_array<std::array<uint64_t,(N+63)/64>>{using Base=_bit_array<std::array<uint64_t,(N+63)/64>>;using Base::Base,Base::words,Base::data;constexpr bit_array():Base(N){}};struct dynamic_bit_array:_bit_array<std::vector<uint64_t>>{using Base=_bit_array<std::vector<uint64_t>>;using Base::Base,Base::words;constexpr dynamic_bit_array(size_t N):Base(N){data.resize(words);}};}
6+
CP_ALGO_BIT_PRAGMA_PUSHnamespace cp_algo::structures{template<typename C>concept Resizable=requires(C&c,std::size_t n){c.resize(n);};template<class Cont>struct _bit_array{using word_t=typename Cont::value_type;static constexpr size_t width=bit_width<word_t>;size_t words,n;alignas(32)Cont data;constexpr void resize(size_t N){n=N;words=(n+width-1)/width;if constexpr(Resizable<Cont>){data.resize(words);}else{assert(std::size(data)>=words);}}constexpr _bit_array():data(){if constexpr(!Resizable<Cont>){resize(std::size(data)*width);}else{resize(0);}}constexpr _bit_array(size_t N):data(){resize(N);}constexpr word_t&word(size_t x){return data[x];}constexpr word_t word(size_t x)const{return data[x];}constexpr void set_all(word_t val=-1){for(auto&w:data){w=val;}}constexpr void reset(){set_all(0);}constexpr void set(size_t x){word(x/width)|=1ULL<<(x%width);}constexpr void reset(size_t x){word(x/width)&=~(1ULL<<(x%width));}constexpr void flip(size_t x){word(x/width)^=1ULL<<(x%width);}constexpr bool test(size_t x)const{return(word(x/width)>>(x%width))&1;}constexpr bool operator[](size_t x)const{return test(x);}constexpr size_t size()const{return n;}auto operator<=>(_bit_array const&t)const=default;constexpr _bit_array&xor_hint(_bit_array const&t,size_t hint){for(size_t i=hint/width;i<std::size(data);i++){data[i]^=t.data[i];}return*this;}constexpr _bit_array&operator^=(_bit_array const&t){return xor_hint(t,0);}constexpr _bit_array operator^(_bit_array const&t)const{return _bit_array(*this)^=t;}};template<size_t N>using bit_array=_bit_array<std::array<uint64_t,(N+63)/64>>;using dynamic_bit_array=_bit_array<big_vector<uint64_t>>;}
7+
#pragma GCC pop_options
68
#endif
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef CP_ALGO_STRUCTURES_BIT_ARRAY_UTIL_HPP
2+
#define CP_ALGO_STRUCTURES_BIT_ARRAY_UTIL_HPP
3+
#include "../structures/bit_array.hpp"
4+
#include "../util/bit.hpp"
5+
#include <cstdint>
6+
#include <cstddef>
7+
#include <string>
8+
#include <array>
9+
#include <span>
10+
CP_ALGO_BIT_PRAGMA_PUSHnamespace cp_algo::structures{template<typename BitArray>constexpr void from_string(BitArray&arr,std::span<char>bits){arr.resize(std::size(bits));int64_t i=0;constexpr int width=BitArray::width;for(;i+width<=(int64_t)std::size(bits);i+=width){arr.word(i/width)=read_bits64(bits.data()+i);}for(;i<(int64_t)std::size(bits);i++){if(bits[i]&1){arr.set(i);}}}template<typename BitArray>constexpr big_string to_string(BitArray const&arr){big_string res(arr.words*BitArray::width,'0');for(size_t i=0;i<arr.words;i++){write_bits64(res.data()+i*BitArray::width,arr.word(i));}res.resize(arr.n);return res;}template<typename BitArray>constexpr size_t count(BitArray const&arr,size_t n){size_t res=0;for(size_t i=0;i<n/BitArray::width;i++){res+=std::popcount(arr.word(i));}if(n%BitArray::width){res+=std::popcount(arr.word(n/BitArray::width)&mask(n%BitArray::width));}return res;}template<typename BitArray>constexpr size_t count(BitArray const&arr){return count(arr,arr.n);}template<typename BitArray>constexpr size_t ctz(BitArray const&arr){size_t res=0;size_t i=0;while(i<arr.words&&arr.word(i)==0){res+=BitArray::width;i++;}if(i<arr.words){res+=std::countr_zero(arr.word(i));}return std::min(res,arr.n);}}
11+
#pragma GCC pop_options
12+
#endif

cp-algo/min/util/bit.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,15 @@
22
#define CP_ALGO_UTIL_BIT_HPP
33
#include "../util/simd.hpp"
44
#include <cstdint>
5+
#include <cstddef>
56
#include <array>
67
#include <bit>
7-
CP_ALGO_SIMD_PRAGMA_PUSHnamespace cp_algo{template<typename Uint>constexpr size_t bit_width=sizeof(Uint)*8;uint64_t mask(size_t n){return(1ULL<<n)-1;}size_t order_of_bit(auto x,size_t k){return k?std::popcount(x<<(bit_width<decltype(x)>-k)):0;}[[gnu::target("bmi2")]]inline size_t kth_set_bit(uint64_t x,size_t k){return std::countr_zero(_pdep_u64(1ULL<<k,x));}template<int fl=0>void with_bit_floor(size_t n,auto&&callback){if constexpr(fl>=63){return;}else if(n>>(fl+1)){with_bit_floor<fl+1>(n,callback);}else{callback.template operator()<1ULL<<fl>();}}void with_bit_ceil(size_t n,auto&&callback){with_bit_floor(n,[&]<size_t N>(){if(N==n){callback.template operator()<N>();}else{callback.template operator()<N<<1>();}});}inline uint32_t read_bits(char const*p){return _mm256_movemask_epi8(__m256i(vector_cast<u8x32 const>(p[0])+(127-'0')));}inline uint64_t read_bits64(char const*p){return read_bits(p)|(uint64_t(read_bits(p+32))<<32);}inline void write_bits(char*p,uint32_t bits){static constexpr u8x32 shuffler={0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3};auto shuffled=u8x32(_mm256_shuffle_epi8(__m256i()+bits,__m256i(shuffler)));static constexpr u8x32 mask={1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128};for(int z=0;z<32;z++){p[z]=shuffled[z]&mask[z]?'1':'0';}}inline void write_bits64(char*p,uint64_t bits){write_bits(p,uint32_t(bits));write_bits(p+32,uint32_t(bits>>32));}}
8+
#if defined(__x86_64__) && !defined(CP_ALGO_DISABLE_AVX2)
9+
#define CP_ALGO_BIT_OPS_TARGET _Pragma("GCC target(\"avx2,bmi,bmi2,lzcnt,popcnt\")")
10+
#else
11+
#define CP_ALGO_BIT_OPS_TARGET _Pragma("GCC target(\"bmi,bmi2,lzcnt,popcnt\")")
12+
#endif
13+
#define CP_ALGO_BIT_PRAGMA_PUSH \
14+
_Pragma("GCC push_options")\CP_ALGO_BIT_OPS_TARGETCP_ALGO_BIT_PRAGMA_PUSHnamespace cp_algo{template<typename Uint>constexpr size_t bit_width=sizeof(Uint)*8;uint64_t mask(size_t n){return(1ULL<<n)-1;}size_t order_of_bit(auto x,size_t k){return k?std::popcount(x<<(bit_width<decltype(x)>-k)):0;}inline size_t kth_set_bit(uint64_t x,size_t k){return std::countr_zero(_pdep_u64(1ULL<<k,x));}template<int fl=0>void with_bit_floor(size_t n,auto&&callback){if constexpr(fl>=63){return;}else if(n>>(fl+1)){with_bit_floor<fl+1>(n,callback);}else{callback.template operator()<1ULL<<fl>();}}void with_bit_ceil(size_t n,auto&&callback){with_bit_floor(n,[&]<size_t N>(){if(N==n){callback.template operator()<N>();}else{callback.template operator()<N<<1>();}});}inline uint32_t read_bits(char const*p){return _mm256_movemask_epi8(__m256i(vector_cast<u8x32 const>(p[0])+(127-'0')));}inline uint64_t read_bits64(char const*p){return read_bits(p)|(uint64_t(read_bits(p+32))<<32);}inline void write_bits(char*p,uint32_t bits){static constexpr u8x32 shuffler={0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3};auto shuffled=u8x32(_mm256_shuffle_epi8(__m256i()+bits,__m256i(shuffler)));static constexpr u8x32 mask={1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128};for(int z=0;z<32;z++){p[z]=shuffled[z]&mask[z]?'1':'0';}}inline void write_bits64(char*p,uint64_t bits){write_bits(p,uint32_t(bits));write_bits(p+32,uint32_t(bits>>32));}}
815
#pragma GCC pop_options
916
#endif

cp-algo/min/util/simd.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#define CP_ALGO_SIMD_AVX2_TARGET
1111
#endif
1212
#define CP_ALGO_SIMD_PRAGMA_PUSH \
13-
_Pragma("GCC push_options")\_Pragma("GCC optimize(\"O3,unroll-loops\")")\CP_ALGO_SIMD_AVX2_TARGETCP_ALGO_SIMD_PRAGMA_PUSHnamespace cp_algo{template<typename T,size_t len>using simd[[gnu::vector_size(len*sizeof(T))]]=T;using i64x4=simd<int64_t,4>;using u64x4=simd<uint64_t,4>;using u32x8=simd<uint32_t,8>;using i32x4=simd<int32_t,4>;using u32x4=simd<uint32_t,4>;using i16x4=simd<int16_t,4>;using u8x32=simd<uint8_t,32>;using dx4=simd<double,4>;dx4 abs(dx4 a){return dx4{std::abs(a[0]),std::abs(a[1]),std::abs(a[2]),std::abs(a[3])};}static constexpr dx4 magic=dx4()+(3ULL<<51);inline i64x4 lround(dx4 x){return i64x4(x+magic)-i64x4(magic);}inline dx4 to_double(i64x4 x){return dx4(x+i64x4(magic))-magic;}inline dx4 round(dx4 a){return dx4{std::nearbyint(a[0]),std::nearbyint(a[1]),std::nearbyint(a[2]),std::nearbyint(a[3])};}inline u64x4 low32(u64x4 x){return x&uint32_t(-1);}inline auto swap_bytes(auto x){return decltype(x)(__builtin_shufflevector(u32x8(x),u32x8(x),1,0,3,2,5,4,7,6));}inline u64x4 montgomery_reduce(u64x4 x,uint32_t mod,uint32_t imod){
13+
_Pragma("GCC push_options")\CP_ALGO_SIMD_AVX2_TARGETCP_ALGO_SIMD_PRAGMA_PUSHnamespace cp_algo{template<typename T,size_t len>using simd[[gnu::vector_size(len*sizeof(T))]]=T;using i64x4=simd<int64_t,4>;using u64x4=simd<uint64_t,4>;using u32x8=simd<uint32_t,8>;using i32x4=simd<int32_t,4>;using u32x4=simd<uint32_t,4>;using i16x4=simd<int16_t,4>;using u8x32=simd<uint8_t,32>;using dx4=simd<double,4>;dx4 abs(dx4 a){return dx4{std::abs(a[0]),std::abs(a[1]),std::abs(a[2]),std::abs(a[3])};}static constexpr dx4 magic=dx4()+(3ULL<<51);inline i64x4 lround(dx4 x){return i64x4(x+magic)-i64x4(magic);}inline dx4 to_double(i64x4 x){return dx4(x+i64x4(magic))-magic;}inline dx4 round(dx4 a){return dx4{std::nearbyint(a[0]),std::nearbyint(a[1]),std::nearbyint(a[2]),std::nearbyint(a[3])};}inline u64x4 low32(u64x4 x){return x&uint32_t(-1);}inline auto swap_bytes(auto x){return decltype(x)(__builtin_shufflevector(u32x8(x),u32x8(x),1,0,3,2,5,4,7,6));}inline u64x4 montgomery_reduce(u64x4 x,uint32_t mod,uint32_t imod){
1414
#ifdef __AVX2__
1515
auto x_ninv=u64x4(_mm256_mul_epu32(__m256i(x),__m256i()+imod));x+=u64x4(_mm256_mul_epu32(__m256i(x_ninv),__m256i()+mod));
1616
#else

0 commit comments

Comments
 (0)