12#include "cplib/utils/bit.hpp"
31template <
typename T,
int Bits,
int Offset>
35 using bitmap_t = uint64_t;
36 using size_type = std::size_t;
37 static constexpr int branch_mask = (1 << Bits) - 1;
43 size_type
size()
const {
return size_; }
46 bool empty()
const {
return size_ == 0; }
50 int idx = (val >> Offset) & branch_mask;
51 size_type pos = impl::popcount_low(bitmap, idx);
52 if (!((bitmap >> idx) & 1)) {
53 bitmap |= bitmap_t(1) << idx;
54 children.emplace(children.begin() + pos);
56 bool ret = children[pos].insert(val);
63 int idx = (val >> Offset) & branch_mask;
64 if ((bitmap >> idx) & 1) {
65 size_type pos = impl::popcount_low(bitmap, idx);
66 bool ret = children[pos].erase(val);
68 if (children[pos].
empty()) {
69 bitmap &= ~(bitmap_t(1) << idx);
70 children.erase(children.begin() + pos);
80 int idx = (val >> Offset) & branch_mask;
81 if ((bitmap >> idx) & 1) {
82 size_type pos = impl::popcount_low(bitmap, idx);
83 return children[pos].find(val);
97 int curr_xor_val = (xor_val >> Offset) & branch_mask;
98 int curr_xor_min = port::countr_zero(impl::xor_permute(bitmap, curr_xor_val));
99 size_type pos = impl::popcount_low(bitmap, curr_xor_min ^ curr_xor_val);
100 return (T(curr_xor_min) << Offset) | children[pos].xor_min(xor_val);
104 std::optional<T>
next(T val)
const {
105 int idx = (val >> Offset) & branch_mask;
106 int next_idx = impl::next_set_bit(bitmap, idx);
107 if (next_idx == 64) {
110 size_type pos = impl::popcount_low(bitmap, next_idx);
111 if (next_idx > idx) {
112 return (T(next_idx) << Offset) | *(children[pos].next(0));
114 auto ret = children[pos].next(val);
116 return (T(next_idx) << Offset) | *ret;
118 next_idx = impl::next_set_bit(bitmap, next_idx + 1);
119 if (next_idx == 64) {
122 return (T(next_idx) << Offset) | *(children[pos + 1].next(0));
128 std::optional<T>
prev(T val)
const {
129 int idx = (val >> Offset) & branch_mask;
130 int prev_idx = impl::prev_set_bit(bitmap, idx + 1);
131 if (prev_idx == -1) {
134 size_type pos = impl::popcount_low(bitmap, prev_idx);
135 constexpr T MAX = (T(1) << Offset) - 1;
136 if (prev_idx < idx) {
137 return (T(prev_idx) << Offset) | *(children[pos].
prev(MAX));
139 auto ret = children[pos].prev(val);
141 return (T(prev_idx) << Offset) | *ret;
143 prev_idx = impl::prev_set_bit(bitmap, prev_idx);
144 if (prev_idx == -1) {
147 return (T(prev_idx) << Offset) | *(children[pos - 1].prev(MAX));
155 std::vector<Child> children;
159template <
typename T,
int Bits>
162 using bitmap_t = uint64_t;
163 using size_type = std::size_t;
164 static constexpr int branch_mask = (1 << Bits) - 1;
168 size_type
size()
const {
return port::popcount(bitmap); }
170 bool empty()
const {
return bitmap == 0; }
173 int idx = val & branch_mask;
174 bool ret = !((bitmap >> idx) & 1);
175 bitmap |= bitmap_t(1) << idx;
180 int idx = val & branch_mask;
181 bool ret = (bitmap >> idx) & 1;
182 bitmap &= ~(bitmap_t(1) << idx);
186 bool find(T val)
const {
return (bitmap >> (val & branch_mask)) & 1; }
188 T
xor_min(T xor_val)
const {
return port::countr_zero(impl::xor_permute(bitmap, xor_val & branch_mask)); }
190 std::optional<T>
next(T val)
const {
191 int ret = impl::next_set_bit(bitmap, val & branch_mask);
192 return ret == 64 ? std::nullopt : std::make_optional(ret);
195 std::optional<T>
prev(T val)
const {
196 int ret = impl::prev_set_bit(bitmap, (val & branch_mask) + 1);
197 return ret == -1 ? std::nullopt : std::make_optional(ret);
210template <
typename T,
int U>
Bit trie that manages an ordered set of integers, with compile-time fixed height.
Definition: bit_trie.hpp:32
bool insert(T val)
Insert an elemnent. Returns whether the element is inserted (i.e. doesn't exist before insertion).
Definition: bit_trie.hpp:49
std::optional< T > prev(T val) const
Returns the largest element no larger than the given value, or std::nullopt if it doesn't exist,...
Definition: bit_trie.hpp:128
bool find(T val) const
Returns whether the element exists.
Definition: bit_trie.hpp:79
size_type size() const
Returns the number of elements.
Definition: bit_trie.hpp:43
std::optional< T > next(T val) const
Returns the smallest element no smaller than the given value, or std::nullopt if it doesn't exist.
Definition: bit_trie.hpp:104
bool erase(T val)
Delete an elemnent. Returns whether the element is deleted (i.e. exists before deletion).
Definition: bit_trie.hpp:62
bool empty() const
Returns whether the trie is empty.
Definition: bit_trie.hpp:46
StaticSizedBitTrie()
Creates an empty trie.
Definition: bit_trie.hpp:40
T xor_min(T xor_val) const
Returns the minimum of any element xor the give value.
Definition: bit_trie.hpp:96