8#include "cplib/range/bit_dict.hpp"
22template <typename T, int M = std::numeric_limits<T>::digits>
25 static_assert(M > 0 && M <= std::numeric_limits<T>::digits);
27 static constexpr T max_value = M == std::numeric_limits<T>::digits ? std::numeric_limits<T>::max() : (T(1) << M) - 1;
28 using size_type = BitDict::size_type;
35 std::vector<T> temp = std::move(data);
47 std::unique_ptr<T[]> temp(
new T[
size]);
48 for (
int lvl = M - 1; lvl >= 0; lvl--) {
49 BitDict& dict = wa.bit_dict[lvl];
54 T* out1 = temp.get() + (
size - 1);
55 const auto bit_generator = [&]() {
56 bool bit = (*in >> lvl) & 1;
70 T* data_mid = std::copy(temp.get(), out0, data);
71 std::reverse_copy(out0, temp.get() +
size, data_mid);
77 size_type
size()
const {
return bit_dict[0].size(); }
84 T
get(size_type idx)
const {
86 for (
int lvl = M - 1; lvl >= 0; lvl--) {
87 bool bit = bit_dict[lvl].get(idx);
89 idx = bit_dict[lvl].rank_to_child(idx, bit);
99 T
range_nth(size_type left, size_type right, size_type n)
const {
101 for (
int lvl = M - 1; lvl >= 0; lvl--) {
102 const BitDict& bd = bit_dict[lvl];
103 size_type zero_count = bd.
rank0(right) - bd.
rank0(left);
104 bool bit = n >= zero_count;
105 ret |= T(bit) << lvl;
120 size_type
range_count(size_type left, size_type right, T val)
const {
121 for (
int lvl = M - 1; lvl >= 0; lvl--) {
122 bool bit = (val >> lvl) & 1;
123 left = bit_dict[lvl].rank_to_child(left, bit);
124 right = bit_dict[lvl].rank_to_child(right, bit);
136 return _rangefreq(left, right, low, high, M - 1);
140 std::array<BitDict, M> bit_dict;
142 size_type _rangefreq(size_type left, size_type right, T low, T high,
int lvl)
const {
145 }
else if (high - low == (lvl == M - 1 ? max_value : (T(1) << (lvl + 1)) - 1)) {
148 T bit_mask = T(1) << lvl;
149 const BitDict& bd = bit_dict[lvl];
150 if (bit_mask & (low ^ high)) {
151 T split = ~(bit_mask - 1) & high;
152 return _rangefreq(bd.rank_to_child(left,
false), bd.rank_to_child(right,
false), low, split - 1, lvl - 1) +
153 _rangefreq(bd.rank_to_child(left,
true), bd.rank_to_child(right,
true), split, high, lvl - 1);
155 bool bit = bit_mask & low;
156 return _rangefreq(bd.rank_to_child(left, bit), bd.rank_to_child(right, bit), low, high, lvl - 1);
Static bit sequence with rank query in .
Definition: bit_dict.hpp:73
size_type rank_to_child(size_type idx, bool bit) const
Move one level downwards in a wavelet tree.
Definition: bit_dict.hpp:151
void fill_with_bit_generator(BitGenerator &gen)
Overwrite all bits with a bit generator.
Definition: bit_dict.hpp:112
void build()
Set up auxiliary data to prepare for rank queries.
Definition: bit_dict.hpp:121
size_type rank0(size_type idx) const
Returns the number of 0 bits in the range [0, idx).
Definition: bit_dict.hpp:138
Efficient representation of a wavelet tree, supporting various static range queries.
Definition: wavelet_array.hpp:23
static WaveletArray build_and_sort(T *data, size_type size)
Builds a WaveletArray from a mutable buffer, sorting it in place as a side effect.
Definition: wavelet_array.hpp:45
T get(size_type idx) const
Returns the element at the given index.
Definition: wavelet_array.hpp:84
WaveletArray()
Creates an empty WaveletArray.
Definition: wavelet_array.hpp:31
size_type size() const
Returns the number of elements.
Definition: wavelet_array.hpp:77
size_type range_count(size_type left, size_type right, T val) const
Returns the number of the given value in the range [left, right).
Definition: wavelet_array.hpp:120
size_type range_count_between(size_type left, size_type right, T low, T high) const
Returns the number of elements in the range [left, right) whose values are between [low,...
Definition: wavelet_array.hpp:135
T range_nth(size_type left, size_type right, size_type n) const
Returns the 0-indexed n-th smallest element in the range [left, right).
Definition: wavelet_array.hpp:99
WaveletArray(std::vector< T > &&data)
Creates a WaveletArray by consuming an array of elements.
Definition: wavelet_array.hpp:34