9 std::vector<uint8_t> bits;
10 std::size_t num_bits = 0;
13 static constexpr std::size_t npos = std::numeric_limits<std::size_t>::max();
16 explicit NaiveRmM(
const std::string& s) { build_from_string(s); }
17 NaiveRmM(
const std::vector<std::uint64_t>& words, std::size_t nbits) {
18 build_from_words(words, nbits);
22 void build_from_string(
const std::string& s) {
24 bits.resize(num_bits);
25 for (std::size_t i = 0; i < num_bits; i++) {
26 bits[i] = (s[i] ==
'1');
29 void build_from_words(
const std::vector<std::uint64_t>& words,
32 bits.assign(num_bits, 0);
33 for (std::size_t i = 0; i < num_bits; i++) {
34 const std::size_t w = (i >> 6);
35 bits[i] =
static_cast<uint8_t
>(
36 ((w < words.size() ? words[w] : 0ull) >> (i & 63)) & 1u);
40 inline int bit(std::size_t i)
const {
return bits[i]; }
43 std::size_t rank1(std::size_t i)
const {
48 for (std::size_t p = 0; p < i; p++) {
53 std::size_t rank0(std::size_t i)
const {
return i - rank1(i); }
56 std::size_t select1(std::size_t k)
const {
60 for (std::size_t p = 0; p < num_bits; p++) {
71 std::size_t select0(std::size_t k)
const {
75 for (std::size_t p = 0; p < num_bits; p++) {
85 std::size_t rank10(std::size_t i)
const {
90 for (std::size_t p = 0; p + 1 < i; ++p) {
91 if (bits[p] == 1 && bits[p + 1] == 0) {
99 std::size_t select10(std::size_t k)
const {
103 for (std::size_t p = 0; p + 1 < num_bits; ++p) {
104 if (bits[p] == 1 && bits[p + 1] == 0) {
113 int excess(std::size_t i)
const {
114 return int(2 *
static_cast<long long>(rank1(i)) -
115 static_cast<long long>(i));
118 std::size_t fwdsearch(std::size_t i,
int d)
const {
122 int target = excess(i) + d;
124 for (std::size_t p = i; p < num_bits; ++p) {
125 cur += bits[p] ? +1 : -1;
133 std::size_t bwdsearch(std::size_t i,
int d)
const {
140 int target = excess(i) + d;
143 for (std::size_t p = i; p > 0;) {
145 cur += bits[p] ? -1 : +1;
153 std::size_t range_min_query_pos(std::size_t i, std::size_t j)
const {
154 if (i > j || j >= num_bits) {
157 int cur = 0, mn = std::numeric_limits<int>::max();
158 std::size_t pos = npos;
159 for (std::size_t p = i; p <= j; ++p) {
160 cur += bits[p] ? +1 : -1;
169 int range_min_query_val(std::size_t i, std::size_t j)
const {
170 if (i > j || j >= num_bits) {
173 int cur = 0, mn = std::numeric_limits<int>::max();
174 for (std::size_t p = i; p <= j; ++p) {
175 cur += bits[p] ? +1 : -1;
183 std::size_t range_max_query_pos(std::size_t i, std::size_t j)
const {
184 if (i > j || j >= num_bits) {
187 int cur = 0, mx = std::numeric_limits<int>::min();
188 std::size_t pos = npos;
189 for (std::size_t p = i; p <= j; ++p) {
190 cur += bits[p] ? +1 : -1;
199 int range_max_query_val(std::size_t i, std::size_t j)
const {
200 if (i > j || j >= num_bits) {
203 int cur = 0, mx = std::numeric_limits<int>::min();
204 for (std::size_t p = i; p <= j; ++p) {
205 cur += bits[p] ? +1 : -1;
213 std::size_t mincount(std::size_t i, std::size_t j)
const {
214 if (i > j || j >= num_bits) {
217 int cur = 0, mn = std::numeric_limits<int>::max();
218 for (std::size_t p = i; p <= j; ++p) {
219 cur += bits[p] ? +1 : -1;
226 for (std::size_t p = i; p <= j; ++p) {
227 cur += bits[p] ? +1 : -1;
236 std::size_t minselect(std::size_t i, std::size_t j, std::size_t q)
const {
237 if (i > j || j >= num_bits || q == 0) {
240 int cur = 0, mn = std::numeric_limits<int>::max();
241 for (std::size_t p = i; p <= j; ++p) {
242 cur += bits[p] ? +1 : -1;
248 for (std::size_t p = i; p <= j; ++p) {
249 cur += bits[p] ? +1 : -1;
259 std::size_t close(std::size_t i)
const {
263 return fwdsearch(i, -1);
265 std::size_t open(std::size_t i)
const {
266 if (i == 0 || i > num_bits) {
269 auto r = bwdsearch(i, 0);
270 return (r == npos ? npos : r + 1);
272 std::size_t enclose(std::size_t i)
const {
273 if (i == 0 || i > num_bits) {
276 auto r = bwdsearch(i, -2);
277 return (r == npos ? npos : r + 1);