1#include"../../kyopro_library/template.hpp"
3using ull=
unsigned long long;
5 static const ull
NOTFOUND=0xFFFFFFFFFFFFFFFFLLU;
9 static const ull blockBitNum=16;
10 static const ull LEVEL_L=512;
11 static const ull LEVEL_S=16;
13 vector<
unsigned short>S;
14 vector<
unsigned short>B;
19 const ull s=(n+blockBitNum-1)/blockBitNum+1;
21 this->L.assign(n/LEVEL_L+1,0);
22 this->S.assign(n/LEVEL_S+1,0);
24 void set_bit(
const ull bit,
const ull pos) {
25 assert(bit==0
or bit==1);
26 assert(pos<
this->size);
27 const ull blockPos=pos/blockBitNum;
28 const ull offset=pos%blockBitNum;
30 B.at(blockPos)|=(1LLU<<offset);
32 B.at(blockPos)&=(~(1LLU<<offset));
36 assert(pos<
this->size);
37 const ull blockPos=pos/blockBitNum;
38 const ull offset=pos%blockBitNum;
39 return((B.at(blockPos)>>offset)&1);
43 for(ull i=0;i<=size;i++) {
44 if(i%LEVEL_L==0)L.at(i/LEVEL_L)=num;
45 if(i%LEVEL_S==0)S.at(i/LEVEL_S)=num-L.at(i/LEVEL_L);
46 if(i!=size
and i%blockBitNum==0)num+=
this->pop_count(
this->B.at(i/blockBitNum));
50 ull
rank(
const ull bit,
const ull pos) {
51 assert(bit==0
or bit==1);
52 assert(pos<=
this->size);
54 return L[pos/LEVEL_L]+S[pos/LEVEL_S]+pop_count(B[pos/blockBitNum]&((1<<(pos%blockBitNum))-1));
59 ull
select(
const ull bit,
const ull rank) {
60 assert(bit==0
or bit==1);
62 if(bit==0
and rank>
this->size-
this->numOne)
return NOTFOUND;
63 if(bit==1
and rank>
this->numOne)
return NOTFOUND;
69 ull mid=(left+right)/2;
71 r=(bit)?r:mid*LEVEL_L-L.at(mid);
80 ull small_idx=(large_idx*LEVEL_L)/LEVEL_S;
82 ull left=(large_idx*LEVEL_L)/LEVEL_S;
83 ull right=min(((large_idx+1)*LEVEL_L)/LEVEL_S,(ull)S.size());
85 ull mid=(left+right)/2;
86 ull r=L.at(large_idx)+S.at(mid);
87 r=(bit)?r:mid*LEVEL_S-r;
98 const ull begin_block_idx=(small_idx*LEVEL_S)/blockBitNum;
99 ull total_bit=L.at(large_idx)+S.at(small_idx);
101 total_bit=small_idx*LEVEL_S-total_bit;
104 ull b=pop_count(B.at(begin_block_idx+i));
105 if(bit==0)b=blockBitNum-b;
106 if(total_bit+b>=rank) {
107 ull block=(bit)?B.at(begin_block_idx+i):~B.at(begin_block_idx+i);
108 rank_pos=(begin_block_idx+i)*blockBitNum+select_in_block(block,rank-total_bit);
121 ull pop_count(ull x) {
122 x=(x&0x5555555555555555ULL)+((x>>1)&0x5555555555555555ULL);
123 x=(x&0x3333333333333333ULL)+((x>>2)&0x3333333333333333ULL);
124 x=(x+(x>>4))&0x0f0f0f0f0f0f0f0fULL;
130 ull select_in_block(ull x,ull rank) {
131 ull x1=x-((x&0xAAAAAAAAAAAAAAAALLU)>>1);
132 ull x2=(x1&0x3333333333333333LLU)+((x1>>2)&0x3333333333333333LLU);
133 ull x3=(x2+(x2>>4))&0x0F0F0F0F0F0F0F0FLLU;
136 ull rank_next=(x3>>pos)&0xFFLLU;
137 if(rank<=rank_next)
break;
140 ull v2=(x2>>pos)&0xFLLU;
145 ull v1=(x1>>pos)&0x3LLU;
150 ull v0=(x>>pos)&0x1LLU;
166 vector<SuccinctBitVector>bit_arrays;
167 vector<ull>begin_one;
168 map<ull,ull>begin_alphabet;
169 vector<vector<ull>>cumulative_sum;
180 maximum_element=*max_element(a.begin(),a.end())+1;
181 bit_size=get_num_of_bit(maximum_element);
182 if(bit_size==0)bit_size=1;
183 for(ull i=0;i<bit_size;++i) {
185 bit_arrays.push_back(sv);
187 this->begin_one.resize(bit_size);
188 this->cumulative_sum.resize(bit_size+1,vector<ull>(size+1,0));
189 for(ull j=0;j<a.size();++j) {
190 this->cumulative_sum.at(0).at(j+1)=
this->cumulative_sum.at(0).at(j)+a[j];
193 for(ull i=0;i<bit_size;++i) {
195 for(ull j=0;j<v.size();++j) {
197 ull bit=(c>>(bit_size-i-1))&1;
200 bit_arrays.at(i).set_bit(0,j);
203 this->begin_one.at(i)=temp.size();
204 for(ull j=0;j<v.size();++j) {
206 ull bit=(c>>(bit_size-i-1))&1;
209 bit_arrays.at(i).set_bit(1,j);
212 for(ull j=0;j<temp.size();++j) {
213 this->cumulative_sum.at(i+1).at(j+1)=
this->cumulative_sum.at(i+1).at(j)+temp.at(j);
215 bit_arrays.at(i).build();
218 for(
int i=v.size()-1;i>=0;--i)
this->begin_alphabet[v.at(i)]=i;
226 for(ull i=0;i<bit_arrays.size();++i) {
227 ull bit=bit_arrays.at(i).access(pos);
229 pos=bit_arrays.at(i).rank(bit,pos);
230 if(bit)pos+=
this->begin_one.at(i);
240 if(c>=maximum_element)
return NOTFOUND;
241 if(
this->begin_alphabet.find(c)==
this->begin_alphabet.end())
return NOTFOUND;
242 ull index=
this->begin_alphabet.at(c)+rank;
243 for(ull i=0;i<bit_arrays.size();++i) {
245 if(bit==1)index-=
this->begin_one.at(bit_size-i-1);
246 index=
this->bit_arrays.at(bit_size-i-1).select(bit,index);
267 if((end_pos>size||begin_pos>=end_pos)||(k>=end_pos-begin_pos))
return NOTFOUND;
269 for(ull i=0;i<bit_size;++i) {
270 const ull num_of_zero_begin=bit_arrays.at(i).rank(0,begin_pos);
271 const ull num_of_zero_end=bit_arrays.at(i).rank(0,end_pos);
272 const ull num_of_zero=num_of_zero_end-num_of_zero_begin;
273 const ull bit=(k<num_of_zero)?0:1;
276 begin_pos=
this->begin_one.at(i)+begin_pos-num_of_zero_begin;
277 end_pos=
this->begin_one.at(i)+end_pos-num_of_zero_end;
279 begin_pos=num_of_zero_begin;
280 end_pos=num_of_zero_begin+num_of_zero;
285 for(ull i=0;i<bit_size;++i) {
286 const ull bit=(val>>(bit_size-i-1))&1;
287 left=bit_arrays.at(i).rank(bit,left);
288 if(bit)left+=
this->begin_one.at(i);
290 const ull rank=begin_pos+k-left+1;
298 if(c>=maximum_element)
return 0;
299 if(
this->begin_alphabet.find(c)==
this->begin_alphabet.end())
return 0;
300 for(ull i=0;i<bit_size;++i) {
301 ull bit=(c>>(bit_size-i-1))&1;
302 pos=bit_arrays.at(i).rank(bit,pos);
303 if(bit)pos+=
this->begin_one.at(i);
305 ull begin_pos=
this->begin_alphabet.at(c);
306 return pos-begin_pos;
311 ull
range_freq(ull begin_pos,ull end_pos,ull min_c,ull max_c) {
312 if((end_pos>size||begin_pos>=end_pos)||(min_c>=max_c)||min_c>=maximum_element) {
315 const auto maxi_t=rank_all(max_c,begin_pos,end_pos);
316 const auto mini_t=rank_all(min_c,begin_pos,end_pos);
317 return get<1>(maxi_t)-get<1>(mini_t);
323 auto t=rank_all(c,begin,end);
330 auto t=rank_all(c,begin,end);
338 const ull num=end-begin;
339 if(begin>=end)
return make_tuple(0,0,0);
340 if(c>=maximum_element||end==0)
return make_tuple(0,num,0);
341 ull rank_less_than=0,rank_more_than=0;
342 for(size_t i=0;i<bit_size&&begin<end;++i) {
343 const ull bit=(c>>(bit_size-i-1))&1;
344 const ull rank0_begin=
this->bit_arrays.at(i).rank(0,begin);
345 const ull rank0_end=
this->bit_arrays.at(i).rank(0,end);
346 const ull rank1_begin=begin-rank0_begin;
347 const ull rank1_end=end-rank0_end;
349 rank_less_than+=(rank0_end-rank0_begin);
350 begin=
this->begin_one.at(i)+rank1_begin;
351 end=
this->begin_one.at(i)+rank1_end;
353 rank_more_than+=(rank1_end-rank1_begin);
358 const ull rank=num-rank_less_than-rank_more_than;
359 return make_tuple(rank,rank_less_than,rank_more_than);
367 vector<pair<ull,ull>>result;
368 auto c=[](
const tuple<ull,ull,ull,ull,ull>&l,
const tuple<ull,ull,ull,ull,ull>&r) {
369 if(get<0>(l)!=get<0>(r))
return get<0>(l)<get<0>(r);
370 if(get<3>(l)!=get<3>(r))
return get<3>(l)>get<3>(r);
371 if(get<4>(l)!=get<4>(r))
return get<4>(l)>get<4>(r);
374 std::priority_queue<tuple<ull,ull,ull,ull,ull>,vector<tuple<ull,ull,ull,ull,ull>>,
decltype(c)>que(c);
375 que.push(make_tuple(e-s,s,e,0,0));
376 while(
not que.empty()) {
377 auto element=que.top();
379 ull width,left,right,depth,value;
380 tie(width,left,right,depth,value)=element;
381 if(depth>=
this->bit_size) {
382 result.emplace_back(make_pair(value,right-left));
383 if(result.size()>=k)
break;
386 const ull left0=
this->bit_arrays.at(depth).rank(0,left);
387 const ull right0=
this->bit_arrays.at(depth).rank(0,right);
388 if(left0<right0)que.push(make_tuple(right0-left0,left0,right0,depth+1,value));
389 const ull left1=
this->begin_one.at(depth)+
this->bit_arrays.at(depth).rank(1,left);
390 const ull right1=
this->begin_one.at(depth)+
this->bit_arrays.at(depth).rank(1,right);
391 if(left1<right1)que.push(make_tuple(right1-left1,left1,right1,depth+1,value|(1<<(bit_size-depth-1))));
398 ull
range_sum(
const ull begin,
const ull end,
const ull x,
const ull y) {
399 return range_sum(begin,end,0,0,x,y);
402 ull
prev_value(
const ull begin_pos,
const ull end_pos,
const ull x,ull y) {
403 assert(end_pos<=size);
405 if(y>maximum_element)y=maximum_element;
406 if(begin_pos>=end_pos)
return NOTFOUND;
407 if(x>=maximum_element||end_pos==0)
return NOTFOUND;
409 stack<tuple<ull,ull,ull,ull,
bool>>s;
410 s.emplace(make_tuple(begin_pos,end_pos,0,0,
true));
411 while(
not s.empty()) {
414 tie(b,e,depth,c,tight)=s.top();
416 if(depth==bit_size) {
420 const ull bit=(y>>(bit_size-depth-1))&1;
421 const ull rank0_begin=
this->bit_arrays.at(depth).rank(0,b);
422 const ull rank0_end=
this->bit_arrays.at(depth).rank(0,e);
423 const ull rank1_begin=b-rank0_begin;
424 const ull rank1_end=e-rank0_end;
425 const ull b0=rank0_begin;
426 const ull e0=rank0_end;
428 const ull c0=((c<<1)|0);
429 s.emplace(make_tuple(b0,e0,depth+1,c0,tight
and bit==0));
431 const ull b1=
this->begin_one.at(depth)+rank1_begin;
432 const ull e1=
this->begin_one.at(depth)+rank1_end;
434 if(
not tight
or bit==1) {
435 const auto c1=((c<<1)|1);
436 s.emplace(make_tuple(b1,e1,depth+1,c1,tight));
442 ull
next_value(
const ull begin_pos,
const ull end_pos,
const ull x,
const ull y) {
443 assert(end_pos<=size);
445 if(begin_pos>=end_pos)
return NOTFOUND;
446 if(x>=maximum_element||end_pos==0)
return NOTFOUND;
447 stack<tuple<ull,ull,ull,ull,
bool>>s;
448 s.emplace(make_tuple(begin_pos,end_pos,0,0,
true));
449 while(
not s.empty()) {
452 tie(b,e,depth,c,tight)=s.top();
454 if(depth==bit_size) {
458 const ull bit=(x>>(bit_size-depth-1))&1;
459 const ull rank0_begin=
this->bit_arrays.at(depth).rank(0,b);
460 const ull rank0_end=
this->bit_arrays.at(depth).rank(0,e);
461 const ull rank1_begin=b-rank0_begin;
462 const ull rank1_end=e-rank0_end;
463 const ull b1=
this->begin_one.at(depth)+rank1_begin;
464 const ull e1=
this->begin_one.at(depth)+rank1_end;
466 const auto c1=((c<<1)|1);
467 s.emplace(make_tuple(b1,e1,depth+1,c1,tight
and bit==1));
469 const ull b0=rank0_begin;
470 const ull e0=rank0_end;
472 if(
not tight
or bit==0) {
473 const ull c0=((c<<1)|0);
474 s.emplace(make_tuple(b0,e0,depth+1,c0,tight));
483 vector<tuple<ull,ull,ull>>intersection;
484 queue<tuple<ull,ull,ull,ull,ull,ull>>que;
485 que.push(make_tuple(_s1,_e1,_s2,_e2,0,0));
486 while(
not que.empty()) {
489 ull s1,e1,s2,e2,depth,value;
490 tie(s1,e1,s2,e2,depth,value)=e;
491 if(depth>=
this->bit_size) {
492 intersection.emplace_back(make_tuple(value,e1-s1,e2-s2));
495 ull s1_0=
this->bit_arrays.at(depth).rank(0,s1);
496 ull e1_0=
this->bit_arrays.at(depth).rank(0,e1);
497 ull s2_0=
this->bit_arrays.at(depth).rank(0,s2);
498 ull e2_0=
this->bit_arrays.at(depth).rank(0,e2);
499 if(s1_0!=e1_0
and s2_0!=e2_0)que.push(make_tuple(s1_0,e1_0,s2_0,e2_0,depth+1,value));
500 ull s1_1=
this->begin_one.at(depth)+
this->bit_arrays.at(depth).rank(1,s1);
501 ull e1_1=
this->begin_one.at(depth)+
this->bit_arrays.at(depth).rank(1,e1);
502 ull s2_1=
this->begin_one.at(depth)+
this->bit_arrays.at(depth).rank(1,s2);
503 ull e2_1=
this->begin_one.at(depth)+
this->bit_arrays.at(depth).rank(1,e2);
504 if(s1_1!=e1_1
and s2_1!=e2_1)que.push(make_tuple(s1_1,e1_1,s2_1,e2_1,depth+1,value|(1<<(bit_size-depth-1))));
510 ull get_num_of_bit(ull x) {
514 while(x>>bit_num)++bit_num;
517 ull range_sum(
const ull begin,
const ull end,
const ull depth,
const ull c,
const ull x,
const ull y) {
518 if(begin==end)
return 0;
519 if(depth==bit_size) {
520 if(x<=c
and c<y)
return c*(end-begin);
523 const ull next_c=((ull)1<<(bit_size-depth-1))|c;
524 const ull all_one_c=(((ull)1<<(bit_size-depth-1))-1)|next_c;
525 if(all_one_c<x
or y<=c)
return 0;
526 if(x<=c
and all_one_c<y)
return this->cumulative_sum.at(depth).at(end)-
this->cumulative_sum.at(depth).at(begin);
527 const ull rank0_begin=
this->bit_arrays.at(depth).rank(0,begin);
528 const ull rank0_end=
this->bit_arrays.at(depth).rank(0,end);
529 const ull rank1_begin=begin-rank0_begin;
530 const ull rank1_end=end-rank0_end;
531 return range_sum(rank0_begin,rank0_end,depth+1,c,x,y)+range_sum(
this->begin_one.at(depth)+rank1_begin,
this->begin_one[depth]+rank1_end,depth+1,next_c,x,y);
void set_bit(const ull bit, const ull pos)
ull rank(const ull bit, const ull pos)
SuccinctBitVector(const ull n)
static const ull NOTFOUND
ull access(const ull pos)
ull select(const ull bit, const ull rank)
Wavelet Matrix https://github.com/MitI-7/WaveletMatrix/tree/master/WaveletMatrix https://miti-7....
vector< tuple< ull, ull, ull > > intersect(ull _s1, ull _e1, ull _s2, ull _e2)
ull rank_more_than(ull c, ull begin, ull end)
区間 [l, r) の c より大きい値の数
ull range_freq(ull begin_pos, ull end_pos, ull min_c, ull max_c)
区間 [l, r) の [min_c, max_c) に入る値の個数
ull range_sum(const ull begin, const ull end, const ull x, const ull y)
区間 [l, r) で [x, y) に入る値の総和
ull select(ull c, ull rank)
rank 番目の c の位置 +1 を返す
ull quantile_range(ull begin_pos, ull end_pos, ull k)
区間 [l, r) で k 番目に小さい値のインデックスを返す
WaveletMatrix(const vector< ull > &a)
コンストラクタ
vector< pair< ull, ull > > topk(ull begin, ull end, ull k)
区間 [l, r) で出現回数が多い順に k 個の (値, 頻度) を返す
ull access(ull pos)
a[pos] を返す
ull next_value(const ull begin_pos, const ull end_pos, const ull x, const ull y)
ull max_range(ull begin_pos, ull end_pos)
区間 [l, r) で最大のインデックスを返す
ull min_range(ull begin_pos, ull end_pos)
区間 [l, r) で最小のインデックスを返す
tuple< ull, ull, ull > rank_all(const ull c, ull begin, ull end)
区間 [l, r) の (c と同じ値の数, c より小さい値の数, c より大きい値の数)
ull rank(ull c, ull pos)
区間 [0, pos) の c の数
ull rank_less_than(ull c, ull begin, ull end)
区間 [l, r) の c より小さい値の数
ull prev_value(const ull begin_pos, const ull end_pos, const ull x, ull y)
static const ull NOTFOUND