Skip to content

Commit 4c397a9

Browse files
chore: update minified library versions
1 parent 7a28ec7 commit 4c397a9

File tree

12 files changed

+23
-12
lines changed

12 files changed

+23
-12
lines changed
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#ifndef CP_ALGO_NUMBER_THEORY_DIRICHLET_HPP
22
#define CP_ALGO_NUMBER_THEORY_DIRICHLET_HPP
3+
#include "../util/big_alloc.hpp"
34
#include <algorithm>
45
#include <cstdint>
56
#include <ranges>
67
#include <vector>
78
#include <cmath>
8-
namespace cp_algo::math{auto floor_stats(int64_t n){auto rt_n=int(sqrtl(n));return std::pair{rt_n,2*rt_n-(n/rt_n==rt_n)};}auto floor_generator(int64_t n){auto[rt_n,num_floors]=floor_stats(n);return[n,rt_n=rt_n,num_floors=num_floors](int k){return k<=rt_n?int64_t(k):n/int64_t(num_floors-k+1);};}auto floors(int64_t n){auto[_,m]=floor_stats(n);return std::views::iota(0,m+1)|std::views::transform(floor_generator(n));}struct interval{int lo,hi;auto operator<=>(const interval&)const=default;};enum exec_mode{standard,reverse};template<exec_mode mode=standard>void Dirichlet_helper(int64_t n,auto&H,auto const&F,auto const&G,auto&&callback){auto[rt_n,num_floors]=floor_stats(n);auto to_ord=[&](int64_t k){return k<=rt_n?int(k):num_floors-int(n/k)+1;};auto call=[&](interval x,interval y,interval z){auto Fx=F[x.hi]-F[x.lo-1];auto Fy=F[y.hi]-F[y.lo-1];decltype(Fx)Gx,Gy;if constexpr(mode==standard){Gy=G[y.hi]-G[y.lo-1];Gx=G[x.hi]-G[x.lo-1];}else{Gy=G[y.lo-1]-G[y.hi];Gx=G[x.lo-1]-G[x.hi];}auto t=Fx*Gy;if(x!=y)[[likely]]{t+=Fy*Gx;}H[z.lo]+=t;if(z.hi<num_floors)[[likely]]{H[z.hi+1]-=t;}};for(int k=2;k<=num_floors;++k){if(k>rt_n){int z=num_floors-k+1;for(int x=2;;x++){int y_lo_ord=std::max(x,z)+1;int y_hi_ord=to_ord(n/(x*z));if(y_hi_ord<y_lo_ord)break;call({x,x},{y_lo_ord,y_hi_ord},{k,k});}}H[k]=callback(k);if(k<=rt_n){int x=k;for(int y=2;y<k;++y){int z_lo_ord=to_ord(1LL*x*y);int z_hi_ord=to_ord(n/x);if(z_hi_ord<z_lo_ord)break;call({x,x},{y,y},{z_lo_ord,z_hi_ord});}int z_lo_ord=to_ord(1LL*x*x);call({x,x},{x,x},{z_lo_ord,num_floors});}}}auto Dirichlet_mul(auto const&F,auto const&G,int64_t n){auto m=size(F);std::decay_t<decltype(F)>H(m);H[1]=F[1]*G[1];Dirichlet_helper(n,H,F,G,[&](auto k){return H[k]+(F[k]-F[k-1])*G[1]+(G[k]-G[k-1])*F[1];});partial_sum(begin(H),end(H),begin(H));return H;}void Dirichlet_div_inplace(auto&H,auto const&G,int64_t n){auto Gi=G[1].inv();H[0]-=H[0];adjacent_difference(begin(H),end(H),begin(H));H[1]*=Gi;Dirichlet_helper<reverse>(n,H,H,G,[&](auto k){return(Gi*(H[k]-(G[k]-G[k-1])*H[1]))+H[k-1];});}auto Dirichlet_div(auto const&H,auto const&G,int64_t n){auto m=std::size(G);auto F=H|std::views::take(m)|std::ranges::to<std::vector>();Dirichlet_div_inplace(F,G,n);return F;}}
9+
namespace cp_algo::math{auto floor_stats(int64_t n){auto rt_n=int(sqrtl(n));return std::pair{rt_n,2*rt_n-(n/rt_n==rt_n)};}auto floor_generator(int64_t n){auto[rt_n,num_floors]=floor_stats(n);return[n,rt_n=rt_n,num_floors=num_floors](int k){return k<=rt_n?int64_t(k):n/int64_t(num_floors-k+1);};}auto floors(int64_t n){auto[_,m]=floor_stats(n);return std::views::iota(0,m+1)|std::views::transform(floor_generator(n));}struct interval{int lo,hi;auto operator<=>(const interval&)const=default;};enum exec_mode{standard,reverse};template<exec_mode mode=standard>void Dirichlet_helper(int64_t n,auto&H,auto const&F,auto const&G,auto&&callback){auto[rt_n,num_floors]=floor_stats(n);auto to_ord=[&](int64_t k){return k<=rt_n?int(k):num_floors-int(n/k)+1;};auto call=[&](interval x,interval y,interval z){auto Fx=F[x.hi]-F[x.lo-1];auto Fy=F[y.hi]-F[y.lo-1];decltype(Fx)Gx,Gy;if constexpr(mode==standard){Gy=G[y.hi]-G[y.lo-1];Gx=G[x.hi]-G[x.lo-1];}else{Gy=G[y.lo-1]-G[y.hi];Gx=G[x.lo-1]-G[x.hi];}auto t=Fx*Gy;if(x!=y)[[likely]]{t+=Fy*Gx;}H[z.lo]+=t;if(z.hi<num_floors)[[likely]]{H[z.hi+1]-=t;}};for(int k=2;k<=num_floors;++k){if(k>rt_n){int z=num_floors-k+1;for(int x=2;;x++){int y_lo_ord=std::max(x,z)+1;int y_hi_ord=to_ord(n/(x*z));if(y_hi_ord<y_lo_ord)break;call({x,x},{y_lo_ord,y_hi_ord},{k,k});}}H[k]=callback(k);if(k<=rt_n){int x=k;for(int y=2;y<k;++y){int z_lo_ord=to_ord(1LL*x*y);int z_hi_ord=to_ord(n/x);if(z_hi_ord<z_lo_ord)break;call({x,x},{y,y},{z_lo_ord,z_hi_ord});}int z_lo_ord=to_ord(1LL*x*x);call({x,x},{x,x},{z_lo_ord,num_floors});}}}auto Dirichlet_mul(auto const&F,auto const&G,int64_t n){auto m=size(F);std::decay_t<decltype(F)>H(m);H[1]=F[1]*G[1];Dirichlet_helper(n,H,F,G,[&](auto k){return H[k]+(F[k]-F[k-1])*G[1]+(G[k]-G[k-1])*F[1];});partial_sum(begin(H),end(H),begin(H));return H;}void Dirichlet_div_inplace(auto&H,auto const&G,int64_t n){auto Gi=G[1].inv();H[0]-=H[0];adjacent_difference(begin(H),end(H),begin(H));H[1]*=Gi;Dirichlet_helper<reverse>(n,H,H,G,[&](auto k){return(Gi*(H[k]-(G[k]-G[k-1])*H[1]))+H[k-1];});}auto Dirichlet_div(auto const&H,auto const&G,int64_t n){auto m=std::size(G);auto F=H|std::views::take(m)|std::ranges::to<big_vector>();Dirichlet_div_inplace(F,G,n);return F;}}
910
#endif
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#ifndef CP_ALGO_NUMBER_THEORY_EULER_HPP
22
#define CP_ALGO_NUMBER_THEORY_EULER_HPP
33
#include "factorize.hpp"
4-
namespace cp_algo::math{auto euler_phi(auto m){auto primes=to<std::vector>(factorize(m));std::ranges::sort(primes);auto[from,to]=std::ranges::unique(primes);primes.erase(from,to);auto ans=m;for(auto it:primes){ans-=ans/it;}return ans;}template<modint_type base>auto period(base x){auto ans=euler_phi(base::mod());base x0=bpow(x,ans);for(auto t:factorize(ans)){while(ans%t==0&&x0*bpow(x,ans/t)==x0){ans/=t;}}return ans;}template<typename _Int>_Int primitive_root(_Int p){using Int=std::make_signed_t<_Int>;using base=dynamic_modint<Int>;return base::with_mod(p,[p](){base t=1;while(period(t)!=p-1){t=random::rng();}return t.getr();});}}
4+
#include "../util/big_alloc.hpp"
5+
namespace cp_algo::math{auto euler_phi(auto m){auto primes=to<big_vector>(factorize(m));std::ranges::sort(primes);auto[from,to]=std::ranges::unique(primes);primes.erase(from,to);auto ans=m;for(auto it:primes){ans-=ans/it;}return ans;}template<modint_type base>auto period(base x){auto ans=euler_phi(base::mod());base x0=bpow(x,ans);for(auto t:factorize(ans)){while(ans%t==0&&x0*bpow(x,ans/t)==x0){ans/=t;}}return ans;}template<typename _Int>_Int primitive_root(_Int p){using Int=std::make_signed_t<_Int>;using base=dynamic_modint<Int>;return base::with_mod(p,[p](){base t=1;while(period(t)!=p-1){t=random::rng();}return t.getr();});}}
56
#endif

cp-algo/min/number_theory/two_squares.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
#define CP_ALGO_NUMBER_THEORY_TWO_SQUARES_HPP
33
#include "euler.hpp"
44
#include "../util/complex.hpp"
5+
#include "../util/big_alloc.hpp"
56
#include <cassert>
67
#include <utility>
78
#include <vector>
89
#include <map>
9-
namespace cp_algo::math{template<typename T>using gaussint=complex<T>;template<typename _Int>auto two_squares_prime_any(_Int p){if(p==2){return gaussint<_Int>{1,1};}assert(p%4==1);using Int=std::make_signed_t<_Int>;using base=dynamic_modint<Int>;return base::with_mod(p,[&](){base g=primitive_root(p);int64_t i=bpow(g,(p-1)/4).getr();int64_t q0=1,q1=0;int64_t r=i,m=p;do{int64_t d=r/m;q0=std::exchange(q1,q0+d*q1);r=std::exchange(m,r%m);}while(q1<p/q1);return gaussint<_Int>{q0,(base(i)*base(q0)).rem()};});}template<typename Int>std::vector<gaussint<Int>>two_squares_all(Int n){if(n==0){return{0};}auto primes=factorize(n);std::map<Int,int>cnt;for(auto p:primes){cnt[p]++;}std::vector<gaussint<Int>>res={1};for(auto[p,c]:cnt){std::vector<gaussint<Int>>nres;if(p%4==3){if(c%2==0){auto mul=bpow(gaussint<Int>(p),c/2);for(auto p:res){nres.push_back(p*mul);}}}else if(p%4==1){auto base=two_squares_prime_any(p);for(int i=0;i<=c;i++){auto mul=bpow(base,i)*bpow(conj(base),c-i);for(auto p:res){nres.push_back(p*mul);}}}else if(p%4==2){auto mul=bpow(gaussint<Int>(1,1),c);for(auto p:res){nres.push_back(p*mul);}}res=nres;}std::vector<gaussint<Int>>nres;for(auto p:res){while(p.real()<0||p.imag()<0){p*=gaussint<Int>(0,1);}nres.push_back(p);if(!p.real()||!p.imag()){nres.emplace_back(p.imag(),p.real());}}return nres;}}
10+
namespace cp_algo::math{template<typename T>using gaussint=complex<T>;template<typename _Int>auto two_squares_prime_any(_Int p){if(p==2){return gaussint<_Int>{1,1};}assert(p%4==1);using Int=std::make_signed_t<_Int>;using base=dynamic_modint<Int>;return base::with_mod(p,[&](){base g=primitive_root(p);int64_t i=bpow(g,(p-1)/4).getr();int64_t q0=1,q1=0;int64_t r=i,m=p;do{int64_t d=r/m;q0=std::exchange(q1,q0+d*q1);r=std::exchange(m,r%m);}while(q1<p/q1);return gaussint<_Int>{q0,(base(i)*base(q0)).rem()};});}template<typename Int>big_vector<gaussint<Int>>two_squares_all(Int n){if(n==0){return{0};}auto primes=factorize(n);std::map<Int,int>cnt;for(auto p:primes){cnt[p]++;}big_vector<gaussint<Int>>res={1};for(auto[p,c]:cnt){big_vector<gaussint<Int>>nres;if(p%4==3){if(c%2==0){auto mul=bpow(gaussint<Int>(p),c/2);for(auto p:res){nres.push_back(p*mul);}}}else if(p%4==1){auto base=two_squares_prime_any(p);for(int i=0;i<=c;i++){auto mul=bpow(base,i)*bpow(conj(base),c-i);for(auto p:res){nres.push_back(p*mul);}}}else if(p%4==2){auto mul=bpow(gaussint<Int>(1,1),c);for(auto p:res){nres.push_back(p*mul);}}res=nres;}big_vector<gaussint<Int>>nres;for(auto p:res){while(p.real()<0||p.imag()<0){p*=gaussint<Int>(0,1);}nres.push_back(p);if(!p.real()||!p.imag()){nres.emplace_back(p.imag(),p.real());}}return nres;}}
1011
#endif

cp-algo/min/structures/dsu.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef CP_ALGO_STRUCTURES_DSU_HPP
22
#define CP_ALGO_STRUCTURES_DSU_HPP
3+
#include "../util/big_alloc.hpp"
34
#include <numeric>
45
#include <vector>
5-
namespace cp_algo::structures{struct disjoint_set_union{disjoint_set_union(int n):par(n){std::iota(begin(par),end(par),0);}int get(int v){return v==par[v]?v:par[v]=get(par[v]);}bool uni(int a,int b){a=get(a);b=get(b);par[a]=b;return a!=b;}private:std::vector<int>par;};using dsu=disjoint_set_union;}
6+
namespace cp_algo::structures{struct disjoint_set_union{disjoint_set_union(int n):par(n){std::iota(begin(par),end(par),0);}int get(int v){return v==par[v]?v:par[v]=get(par[v]);}bool uni(int a,int b){a=get(a);b=get(b);par[a]=b;return a!=b;}private:big_vector<int>par;};using dsu=disjoint_set_union;}
67
#endif

cp-algo/min/structures/eertree.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#ifndef CP_ALGO_STRUCTURES_EERTREE_HPP
22
#define CP_ALGO_STRUCTURES_EERTREE_HPP
3+
#include "../util/big_alloc.hpp"
34
#include <forward_list>
45
#include <functional>
56
#include <iostream>
67
#include <vector>
78
#include <string>
8-
namespace cp_algo::structures{template<int sigma=26,char mch='a'>struct eertree{eertree(size_t q){q+=2;s=std::string(q,-1);len=par=link=std::vector(q,0);to.resize(q);link[0]=1;len[1]=-1;}int get_link(int v)const{while(s[n-1]!=s[n-len[v]-2]){v=link[v];}return v;}int get(int v,int c)const{for(int cu:to[v]){if(char(cu)==c){return cu>>8;}}return 0;}void add_letter(char c){c-='a';s[n++]=c;last=get_link(last);if(!get(last,c)){int u=get(get_link(link[last]),c);link[sz]=u;par[sz]=last;len[sz]=len[last]+2;to[last].emplace_front((sz++<<8)|c);}last=get(last,c);}int sufpal(auto&&adjust)const{return adjust(last);}int sufpal()const{return sufpal(std::identity{});}void print(auto&&adjust)const{std::cout<<sz-2<<"\n";for(int i=2;i<sz;i++){std::cout<<adjust(par[i])<<' '<<adjust(link[i])<<"\n";}}void print()const{print(std::identity{});}private:std::vector<std::forward_list<int>>to;std::vector<int>len,link,par;std::string s;int n=1,sz=2,last=0;};}
9+
namespace cp_algo::structures{template<int sigma=26,char mch='a'>struct eertree{eertree(size_t q){q+=2;s=std::string(q,-1);len=par=link=big_vector(q,0);to.resize(q);link[0]=1;len[1]=-1;}int get_link(int v)const{while(s[n-1]!=s[n-len[v]-2]){v=link[v];}return v;}int get(int v,int c)const{for(int cu:to[v]){if(char(cu)==c){return cu>>8;}}return 0;}void add_letter(char c){c-='a';s[n++]=c;last=get_link(last);if(!get(last,c)){int u=get(get_link(link[last]),c);link[sz]=u;par[sz]=last;len[sz]=len[last]+2;to[last].emplace_front((sz++<<8)|c);}last=get(last,c);}int sufpal(auto&&adjust)const{return adjust(last);}int sufpal()const{return sufpal(std::identity{});}void print(auto&&adjust)const{std::cout<<sz-2<<"\n";for(int i=2;i<sz;i++){std::cout<<adjust(par[i])<<' '<<adjust(link[i])<<"\n";}}void print()const{print(std::identity{});}private:big_vector<std::forward_list<int>>to;big_vector<int>len,link,par;std::string s;int n=1,sz=2,last=0;};}
910
#endif

cp-algo/min/structures/fenwick.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef CP_ALGO_STRUCTURES_FENWICK_HPP
22
#define CP_ALGO_STRUCTURES_FENWICK_HPP
3+
#include "../util/big_alloc.hpp"
34
#include <cassert>
45
#include <vector>
5-
namespace cp_algo::structures{template<typename Op>struct inverse_op{};template<typename T>struct inverse_op<std::plus<T>>{static T apply(T const&a,T const&b){return a-b;}};template<typename T>struct inverse_op<std::multiplies<T>>{static T apply(T const&a,T const&b){return a/b;}};template<typename T,std::ranges::range Container=std::vector<T>,typename Op=std::plus<T>>struct fenwick{Op op;size_t n;Container data;fenwick(auto&&range,Op&&op=Op{}):op(std::move(op)){assign(std::move(range));}void to_prefix_folds(){for(size_t i=1;i<n;i++){if(i+(i&-i)<=n){data[i+(i&-i)]=op(data[i+(i&-i)],data[i]);}}}void assign(auto&&range){n=size(range)-1;data=std::move(range);to_prefix_folds();}void update(size_t x,T const&v){for(++x;x<=n;x+=x&-x){data[x]=op(data[x],v);}}T prefix_fold(size_t r)const{assert(r<=n);T res={};for(;r;r-=r&-r){res=op(res,data[r]);}return res;}T range_fold(size_t l,size_t r)const{return inverse_op<Op>::apply(prefix_fold(r),prefix_fold(l));}auto prefix_lower_bound(T k)const{size_t x=0;T pref={};for(size_t i=std::bit_floor(n);i;i/=2){if(x+i<=n&&op(pref,data[x+i])<=k){pref=op(pref,data[x+i]);x+=i;}}return std::pair{x,pref};}};template<std::ranges::range Container,typename Op>fenwick(Container&&,Op&&)->fenwick<std::ranges::range_value_t<Container>,Container,Op>;template<std::ranges::range Container>fenwick(Container&&)->fenwick<std::ranges::range_value_t<Container>,Container>;auto maxer=[](auto const&a,auto const&b){return std::max(a,b);};template<typename T,std::ranges::range Container=std::vector<T>>struct fenwick_max:fenwick<T,Container,decltype(maxer)>{using fenwick<T,Container,decltype(maxer)>::fenwick;};template<std::ranges::range Container>fenwick_max(Container&&)->fenwick_max<std::ranges::range_value_t<Container>,Container>;}
6+
namespace cp_algo::structures{template<typename Op>struct inverse_op{};template<typename T>struct inverse_op<std::plus<T>>{static T apply(T const&a,T const&b){return a-b;}};template<typename T>struct inverse_op<std::multiplies<T>>{static T apply(T const&a,T const&b){return a/b;}};template<typename T,std::ranges::range Container=big_vector<T>,typename Op=std::plus<T>>struct fenwick{Op op;size_t n;Container data;fenwick(auto&&range,Op&&op=Op{}):op(std::move(op)){assign(std::move(range));}void to_prefix_folds(){for(size_t i=1;i<n;i++){if(i+(i&-i)<=n){data[i+(i&-i)]=op(data[i+(i&-i)],data[i]);}}}void assign(auto&&range){n=size(range)-1;data=std::move(range);to_prefix_folds();}void update(size_t x,T const&v){for(++x;x<=n;x+=x&-x){data[x]=op(data[x],v);}}T prefix_fold(size_t r)const{assert(r<=n);T res={};for(;r;r-=r&-r){res=op(res,data[r]);}return res;}T range_fold(size_t l,size_t r)const{return inverse_op<Op>::apply(prefix_fold(r),prefix_fold(l));}auto prefix_lower_bound(T k)const{size_t x=0;T pref={};for(size_t i=std::bit_floor(n);i;i/=2){if(x+i<=n&&op(pref,data[x+i])<=k){pref=op(pref,data[x+i]);x+=i;}}return std::pair{x,pref};}};template<std::ranges::range Container,typename Op>fenwick(Container&&,Op&&)->fenwick<std::ranges::range_value_t<Container>,Container,Op>;template<std::ranges::range Container>fenwick(Container&&)->fenwick<std::ranges::range_value_t<Container>,Container>;auto maxer=[](auto const&a,auto const&b){return std::max(a,b);};template<typename T,std::ranges::range Container=big_vector<T>>struct fenwick_max:fenwick<T,Container,decltype(maxer)>{using fenwick<T,Container,decltype(maxer)>::fenwick;};template<std::ranges::range Container>fenwick_max(Container&&)->fenwick_max<std::ranges::range_value_t<Container>,Container>;}
67
#endif

cp-algo/min/structures/segtree.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef CP_ALGO_STRUCTURES_SEGMENT_TREE_HPP
22
#define CP_ALGO_STRUCTURES_SEGMENT_TREE_HPP
3+
#include "../util/big_alloc.hpp"
34
#include <vector>
45
#include <numeric>
5-
namespace cp_algo::structures{template<typename meta>struct segtree_t{const size_t N;std::vector<meta>_meta;segtree_t(size_t n):N(n),_meta(4*N){}segtree_t(std::vector<meta>leafs):N(size(leafs)),_meta(4*N){build(leafs);}void pull(size_t v,size_t l,size_t r){if(r-l>1){_meta[v].pull(_meta[2*v],_meta[2*v+1],l,r);}}void push(size_t v,size_t l,size_t r){if(r-l>1){_meta[v].push(&_meta[2*v],&_meta[2*v+1],l,r);}else{_meta[v].push(nullptr,nullptr,l,r);}}void build(auto&a,size_t v,size_t l,size_t r){if(r-l==1){if(l<size(a)){_meta[v]=a[l];}}else{size_t m=std::midpoint(l,r);build(a,2*v,l,m);build(a,2*v+1,m,r);pull(v,l,r);}}void build(auto&a){build(a,1,0,N);}void exec_on_segment(size_t a,size_t b,auto func,auto proceed,auto stop,size_t v,size_t l,size_t r){push(v,l,r);if(r<=a||b<=l||stop(_meta[v])){return;}else if(a<=l&&r<=b&&proceed(_meta[v])){func(_meta[v]);push(v,l,r);}else{size_t m=std::midpoint(l,r);exec_on_segment(a,b,func,proceed,stop,2*v,l,m);exec_on_segment(a,b,func,proceed,stop,2*v+1,m,r);pull(v,l,r);}}static constexpr auto default_true=[](auto const&){return true;};static constexpr auto default_false=[](auto const&){return false;};void exec_on_segment(size_t a,size_t b,auto func,auto proceed,auto stop){exec_on_segment(a,b,func,proceed,stop,1,0,N);}void exec_on_segment(size_t a,size_t b,auto func){exec_on_segment(a,b,func,default_true,default_false);}};}
6+
namespace cp_algo::structures{template<typename meta>struct segtree_t{const size_t N;big_vector<meta>_meta;segtree_t(size_t n):N(n),_meta(4*N){}segtree_t(big_vector<meta>leafs):N(size(leafs)),_meta(4*N){build(leafs);}void pull(size_t v,size_t l,size_t r){if(r-l>1){_meta[v].pull(_meta[2*v],_meta[2*v+1],l,r);}}void push(size_t v,size_t l,size_t r){if(r-l>1){_meta[v].push(&_meta[2*v],&_meta[2*v+1],l,r);}else{_meta[v].push(nullptr,nullptr,l,r);}}void build(auto&a,size_t v,size_t l,size_t r){if(r-l==1){if(l<size(a)){_meta[v]=a[l];}}else{size_t m=std::midpoint(l,r);build(a,2*v,l,m);build(a,2*v+1,m,r);pull(v,l,r);}}void build(auto&a){build(a,1,0,N);}void exec_on_segment(size_t a,size_t b,auto func,auto proceed,auto stop,size_t v,size_t l,size_t r){push(v,l,r);if(r<=a||b<=l||stop(_meta[v])){return;}else if(a<=l&&r<=b&&proceed(_meta[v])){func(_meta[v]);push(v,l,r);}else{size_t m=std::midpoint(l,r);exec_on_segment(a,b,func,proceed,stop,2*v,l,m);exec_on_segment(a,b,func,proceed,stop,2*v+1,m,r);pull(v,l,r);}}static constexpr auto default_true=[](auto const&){return true;};static constexpr auto default_false=[](auto const&){return false;};void exec_on_segment(size_t a,size_t b,auto func,auto proceed,auto stop){exec_on_segment(a,b,func,proceed,stop,1,0,N);}void exec_on_segment(size_t a,size_t b,auto func){exec_on_segment(a,b,func,default_true,default_false);}};}
67
#endif

0 commit comments

Comments
 (0)