#pragma once
template<typenameT,boolSentinel=false>classCompress{std::vector<T>v;boolprepared;public:Compress():prepared(false){ifconstexpr(Sentinel){static_assert(std::numeric_limits<T>::is_specialized,"cannot use Sentinel");v={std::numeric_limits<T>::min(),std::numeric_limits<T>::max()};}}Compress(conststd::vector<T>&w):v(w),prepared(false){ifconstexpr(Sentinel){static_assert(std::numeric_limits<T>::is_specialized,"cannot use Sentinel");v.push_back(std::numeric_limits<T>::min());v.push_back(std::numeric_limits<T>::max());}build();}voidadd(Ta){assert(!prepared);v.push_back(a);}voidbuild(){assert(!prepared);prepared=true;std::ranges::sort(v);autoresult=std::ranges::unique(v);v.erase(result.begin(),result.end());}boolis_prepared()const{returnprepared;}intoperator[](constT&a)const{assert(prepared);autoit=std::ranges::lower_bound(v,a);assert(*it==a);returnstd::distance(v.begin(),it);}intgeq(constT&a)const{assert(prepared);autoit=std::ranges::lower_bound(v,a);returnstd::distance(v.begin(),it);}intgt(constT&a)const{assert(prepared);autoit=std::ranges::upper_bound(v,a);returnstd::distance(v.begin(),it);}intleq(constT&a)const{assert(prepared);autoit=--std::ranges::upper_bound(v,a);returnstd::distance(v.begin(),it);}intlt(constT&a)const{assert(prepared);autoit=--std::ranges::lower_bound(v,a);returnstd::distance(v.begin(),it);}Tr(intid)const{assert(prepared);returnv[id];}boolexist(constT&a)const{assert(prepared);return(*std::ranges::lower_bound(v,a))==a;}intsize()const{returnv.size();}Tmax()const{returnv.back();}Tmin()const{returnv[0];}friendstd::ostream&operator<<(std::ostream&os,constCompress&C){for(inti=0;i<C.v.size();i++)os<<C.v[i]<<":"<<i<<" ";returnos;}};
#line 2 "library/util/Compress.hpp"
template<typenameT,boolSentinel=false>classCompress{std::vector<T>v;boolprepared;public:Compress():prepared(false){ifconstexpr(Sentinel){static_assert(std::numeric_limits<T>::is_specialized,"cannot use Sentinel");v={std::numeric_limits<T>::min(),std::numeric_limits<T>::max()};}}Compress(conststd::vector<T>&w):v(w),prepared(false){ifconstexpr(Sentinel){static_assert(std::numeric_limits<T>::is_specialized,"cannot use Sentinel");v.push_back(std::numeric_limits<T>::min());v.push_back(std::numeric_limits<T>::max());}build();}voidadd(Ta){assert(!prepared);v.push_back(a);}voidbuild(){assert(!prepared);prepared=true;std::ranges::sort(v);autoresult=std::ranges::unique(v);v.erase(result.begin(),result.end());}boolis_prepared()const{returnprepared;}intoperator[](constT&a)const{assert(prepared);autoit=std::ranges::lower_bound(v,a);assert(*it==a);returnstd::distance(v.begin(),it);}intgeq(constT&a)const{assert(prepared);autoit=std::ranges::lower_bound(v,a);returnstd::distance(v.begin(),it);}intgt(constT&a)const{assert(prepared);autoit=std::ranges::upper_bound(v,a);returnstd::distance(v.begin(),it);}intleq(constT&a)const{assert(prepared);autoit=--std::ranges::upper_bound(v,a);returnstd::distance(v.begin(),it);}intlt(constT&a)const{assert(prepared);autoit=--std::ranges::lower_bound(v,a);returnstd::distance(v.begin(),it);}Tr(intid)const{assert(prepared);returnv[id];}boolexist(constT&a)const{assert(prepared);return(*std::ranges::lower_bound(v,a))==a;}intsize()const{returnv.size();}Tmax()const{returnv.back();}Tmin()const{returnv[0];}friendstd::ostream&operator<<(std::ostream&os,constCompress&C){for(inti=0;i<C.v.size();i++)os<<C.v[i]<<":"<<i<<" ";returnos;}};