6 typedef unsigned int qword;
9 typedef unsigned long long qword;
12 #define PBS (sizeof(uint)*8)
18 #define logLL 16 // size of word
24 #define LLL (1<<logLLL)
26 //#define logL (logLL-3)
27 #define logL (logLL-1-5)
41 int __setbit(uint *B, int i,int x) {
46 if (x==0) B[j] &= (~(1<<(D-1-l)));
47 else if (x==1) B[j] |= (1<<(D-1-l));
49 printf("error __setbit x=%d\n",x);
56 int __setbit2(uchar *B, int i,int x) {
61 if (x==0) B[j] &= (~(1<<(8-1-l)));
62 else if (x==1) B[j] |= (1<<(8-1-l));
64 printf("error __setbit2 x=%d\n",x);
71 int __setbits(uint *B, int i, int d, int x) {
75 __setbit(B,i+j,(x>>(d-j-1))&1);
81 int __getbit(uint *B, int i) {
88 return (B[j] >> (D-1-l)) & 1;
92 static int __getbit2(uchar *B, int i) {
99 return (B[j] >> (8-1-l)) & 1;
104 uint __getbits_aux(uint *B, int i, int d) {
109 if (d==8 && (j & 7) == 0) {
111 x = (uint) (((unsigned char*) B)[i]);
112 } else if (i+d <= 2*D) {
113 x = (((qword)B[0]) << D) + B[1];
119 fprintf(stderr, "Warning: %d, %d\n", D, d);
120 x = (((qword)B[0])<<D)+B[1];
123 x &= (((qword)1L<<D)-1)<<D;
133 static uint __getbits(uint *B, int i, int d)
138 x = ((uint64_t *) B)[0];
139 x = (x << 32)|(x >> 32);
140 x = (x << i) >> (2*D - d);
146 #if HAS_NATIVE_POPCOUNT
147 static inline unsigned int popcount(unsigned int n){
148 asm ("popcnt %1, %0" : "=r" (n) : "0" (n));
152 // static inline unsigned int popcount8(unsigned int n) {
153 // return __builtin_popcount(n & 0xff);
156 static inline unsigned int _fast_popcount(uchar x)
158 return __builtin_popcount(x);
163 static const unsigned int _popCount[] = {
164 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,
165 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
166 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
167 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
168 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
169 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
170 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
171 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
172 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
173 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
174 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
175 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
176 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
177 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
178 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
179 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
182 static inline unsigned int
183 _fast_popcount(int x) {
184 return _popCount[x & 0xff];
190 //static unsigned int __selecttbl[8*256];
191 static int built = 0;
193 void make___selecttbl(void) {
199 for (x = 0; x < 256; x++) {
200 __setbits(buf,0,8,x);
201 // for (r=0; r<8; r++) __selecttbl[(r<<8)+x] = -1;
203 for (i=0; i<8; i++) {
204 if (__getbit(buf,i)) {
205 // __selecttbl[(r<<8)+x] = i;
212 int selectd2_save(selectd2 * s, FILE * fp) {
214 wr += fwrite(&s->n,sizeof(uint),1,fp);
215 wr += fwrite(&s->m,sizeof(uint),1,fp);
216 wr += fwrite(&s->size,sizeof(uint),1,fp);
217 wr += fwrite(&s->ss_len,sizeof(uint),1,fp);
218 wr += fwrite(&s->sl_len,sizeof(uint),1,fp);
219 wr += fwrite(s->buf,sizeof(uchar),(s->n+7)/8+1,fp);
220 uint nl = (s->m-1) / L + 1;
221 wr += fwrite(s->lp,sizeof(uint),nl+1,fp);
222 wr += fwrite(s->p,sizeof(uint),nl+1,fp);
223 wr += fwrite(s->ss,sizeof(ushort),s->ss_len,fp);
224 wr += fwrite(s->sl,sizeof(uint),s->sl_len,fp);
225 if(wr!=s->sl_len+s->ss_len+2*(nl+1)+(s->n+7)/8+1+5)
231 int selectd2_load(selectd2 * s, FILE * fp) {
233 rd += fread(&s->n,sizeof(uint),1,fp);
234 rd += fread(&s->m,sizeof(uint),1,fp);
235 rd += fread(&s->size,sizeof(uint),1,fp);
236 rd += fread(&s->ss_len,sizeof(uint),1,fp);
237 rd += fread(&s->sl_len,sizeof(uint),1,fp);
238 s->buf = new uchar[(s->n+7)/8+1];
239 rd += fread(s->buf,sizeof(uchar),(s->n+7)/8+1,fp);
240 uint nl = (s->m-1) / L + 1;
241 s->lp = new uint[nl+1];
242 rd += fread(s->lp,sizeof(uint),nl+1,fp);
243 s->p = new uint[nl+1];
244 rd += fread(s->p,sizeof(uint),nl+1,fp);
245 s->ss = new ushort[s->ss_len];
246 rd += fread(s->ss,sizeof(ushort),s->ss_len,fp);
247 s->sl = new uint[s->sl_len];
248 rd += fread(s->sl,sizeof(uint),s->sl_len,fp);
249 if(rd!=s->sl_len+s->ss_len+2*(nl+1)+(s->n+7)/8+1+5)
255 void selectd2_free(selectd2 * s) {
264 int selectd2_construct(selectd2 *select, int n, uchar *buf) {
272 //make___selecttbl();
275 printf("ERROR: L=%d LLL=%d\n",L,LLL);
280 for (i=0; i<n; i++) m += __getbit2(buf,i);
283 //printf("n=%d m=%d\n",n,m);
289 for (i=0; i<n; i++) {
290 if (__getbit2(buf,i)) {
297 select->size = 0; //ignoring buf, shared with selects3
298 select->lp = new uint[nl+1];
299 for(int k=0;k<nl+1;k++) select->lp[k]=0;
300 select->size += (nl+1)*sizeof(uint);
301 select->p = new uint[nl+1];
302 for(int k=0;k<nl+1;k++) select->p[k]=0;
303 select->size += (nl+1)*sizeof(uint);
305 for (r = 0; r < 2; r++) {
307 for (il = 0; il < nl; il++) {
310 i = min((il+1)*L-1,m-1);
312 //printf("%d ",p-pp);
315 for (is = 0; is < L; is++) {
316 if (il*L+is >= m) break;
317 select->sl[ml*L+is] = s[il*L+is];
320 select->p[il] = -((ml<<logL)+1);
325 for (is = 0; is < L/LLL; is++) {
326 if (il*L+is*LLL >= m) break;
327 select->ss[ms*(L/LLL)+is] = s[il*L+is*LLL] - pp;
330 select->p[il] = ms << (logL-logLLL);
335 select->sl = new uint[ml*L+1];
336 for(int k=0;k<ml*L+1;k++) select->sl[k]=0;
337 select->size += sizeof(uint)*(ml*L+1);
338 select->sl_len = ml*L+1;
339 select->ss = new ushort[ms*(L/LLL)+1];
340 for(int k=0;k<ms*(L/LLL)+1;k++) select->ss[k]=0;
341 select->ss_len = ms*(L/LLL)+1;
342 select->size += sizeof(ushort)*(ms*(L/LLL)+1);
350 int selectd2_select1(selectd2 *select, int i) {
355 if (i <= 0) return -1;
358 il = select->p[i>>logL];
361 //p = select->sl[(il<<logL)+(i & (L-1))];
362 p = select->sl[il+(i & (L-1))];
365 p = select->lp[i>>logL];
366 p += select->ss[il+((i & (L-1))>>logLLL)];
367 r = i - (i & (LLL-1));
369 q = &(select->buf[p>>3]);
372 r -= _fast_popcount(*q >> (8-1-rr));
375 //rr = _popCount[*q];
376 rr = _fast_popcount(*q);
377 if (r + rr >= i) break;
382 p = (q - select->buf) << 3;
383 p += selecttbl[((i-r-1)<<8)+(*q)];
388 int selectd2_select0(selectd2 *select, int i) {
394 if (i <= 0) return -1;
397 il = select->p[i>>logL];
400 return select->sl[il+(i & (L-1))];
403 p = select->lp[i>>logL];
405 p += select->ss[il+((i & (L-1))>>logLLL)];
406 r = i - (i & (LLL-1));
408 q = &(select->buf[p>>3]);
412 uint masked_q = *q ^ 0xff;
414 r -= _fast_popcount(masked_q >> (7-rr));
417 rr = _fast_popcount(masked_q);
419 p = (q - select->buf) << 3;
420 p += selecttbl[((i-r-1)<<8)+masked_q];
425 masked_q = *q ^ 0xff;
430 int selectd2_select(selectd2 *select, int i,int f) {
431 return f ? selectd2_select1(select, i) :
432 selectd2_select0(select, i);
436 int selectd2_select2(selectd2 *select, int i,int f, int *st, int *en) {
449 printf("ERROR: m=%d i=%d\n",select->m,i);
456 il = select->p[i>>logL];
459 //p = select->sl[(il<<logL)+(i & (L-1))];
460 p = select->sl[il+(i & (L-1))];
462 if ((i>>logL) == ((i+1)>>logL)) {
463 p2 = select->sl[il+((i+1) & (L-1))];
466 p2 = selectd2_select(select,i+2,f);
470 p = select->lp[i>>logL];
471 //p += select->ss[(il<<(logL-logLLL))+(i & (L-1))/LLL];
472 p += select->ss[il+((i & (L-1))>>logLLL)];
473 r = i - (i & (LLL-1));
475 q = &(select->buf[p>>3]);
479 //r -= _popCount[*q >> (8-1-rr)];
480 r -= _fast_popcount(*q >> (8-1-rr));
484 //rr = _popCount[*q];
485 rr = _fast_popcount(*q);
486 if (r + rr >= i) break;
491 p = (q - select->buf) << 3;
492 p += selecttbl[((i-r-1)<<8)+(*q)];
494 if ((i>>logL) == ((i+1)>>logL)) {
497 //rr = _popCount[*q];
498 r = _fast_popcount(*q);
499 if (r + rr >= i) break;
503 p2 = (q - select->buf) << 3;
504 p2 += selecttbl[((i-r-1)<<8)+(*q)];
507 p2 = selectd2_select(select,i+2,f);
513 //r -= _popCount[(*q ^ 0xff) >> (8-1-rr)];
514 r -= _fast_popcount((*q ^ 0xff) >> (8-1-rr));
518 //rr = _popCount[*q ^ 0xff];
519 rr = _fast_popcount(*q ^ 0xff);
520 if (r + rr >= i) break;
525 p = (q - select->buf) << 3;
526 p += selecttbl[((i-r-1)<<8)+(*q ^ 0xff)];
528 if ((i>>logL) == ((i+1)>>logL)) {
531 //rr = _popCount[*q ^ 0xff];
532 rr = _fast_popcount(*q ^ 0xff);
533 if (r + rr >= i) break;
537 p2 = (q - select->buf) << 3;
538 p2 += selecttbl[((i-r-1)<<8)+(*q ^ 0xff)];
541 p2 = selectd2_select(select,i+2,f);
551 int selects3_save(selects3 * s, FILE * fp) {
553 wr += fwrite(&s->n,sizeof(uint),1,fp);
554 wr += fwrite(&s->m,sizeof(uint),1,fp);
555 wr += fwrite(&s->size,sizeof(uint),1,fp);
556 wr += fwrite(&s->d,sizeof(uint),1,fp);
557 wr += fwrite(&s->hi_len,sizeof(uint),1,fp);
558 wr += fwrite(&s->low_len,sizeof(uint),1,fp);
559 wr += fwrite(s->hi,sizeof(uchar),s->hi_len,fp);
560 wr += fwrite(s->low,sizeof(uint),s->low_len,fp);
561 if(wr!=(6+s->hi_len+s->low_len))
563 if(selectd2_save(s->sd0,fp)) return 2;
564 if(selectd2_save(s->sd1,fp)) return 3;
569 int selects3_load(selects3 * s, FILE * fp) {
571 rd += fread(&s->n,sizeof(uint),1,fp);
572 rd += fread(&s->m,sizeof(uint),1,fp);
573 rd += fread(&s->size,sizeof(uint),1,fp);
574 rd += fread(&s->d,sizeof(uint),1,fp);
575 rd += fread(&s->hi_len,sizeof(uint),1,fp);
576 rd += fread(&s->low_len,sizeof(uint),1,fp);
577 s->hi = new uchar[s->hi_len];
578 rd += fread(s->hi,sizeof(uchar),s->hi_len,fp);
579 s->low = new uint[s->low_len];
580 rd += fread(s->low,sizeof(uint),s->low_len,fp);
581 if(rd!=(6+s->hi_len+s->low_len))
583 s->sd0 = new selectd2;
584 if(selectd2_load(s->sd0,fp)) return 2;
585 s->sd1 = new selectd2;
586 if(selectd2_load(s->sd1,fp)) return 3;
587 delete [] s->sd0->buf;
588 delete [] s->sd1->buf;
595 void selects3_free(selects3 * s) {
598 //delete [] s->sd0->buf;
599 selectd2_free(s->sd0);
601 selectd2_free(s->sd1);
606 int selects3_construct(selects3 *select, int n, uint *buf) {
614 for (i=0; i<n; i++) m += __getbit(buf,i);
618 if (m == 0) return 0;
629 buf2 = new uchar[(2*m+8-1)/8+1];
630 for(int k=0;k<(2*m+8-1)/8+1;k++) buf2[k]=0;
631 select->hi_len = (2*m+8-1)/8+1;
632 low = new uint[(d*m+PBS-1)/PBS+1];
633 for(uint k=0;k<(d*m+PBS-1)/PBS+1;k++) low[k]=0;
634 select->low_len = (d*m+PBS-1)/PBS+1;
638 select->size = sizeof(uchar)*((2*m+8-1)/8+1) + sizeof(uint)*((d*m+PBS-1)/PBS+1);
640 for (i=0; i<m*2; i++) __setbit2(buf2,i,0);
643 for (i=0; i<n; i++) {
644 if (__getbit(buf,i)) {
645 __setbit2(buf2,(i>>d)+m,1);
646 __setbits(low,m*d,d,i & ((1<<d)-1));
653 select->size += 2*sizeof(selectd2);
655 selectd2_construct(sd1,m*2,buf2);
658 for (i=0; i<m*2; i++) __setbit2(buf2,i,1-__getbit2(buf2,i));
659 selectd2_construct(sd0,m*2,buf2);
662 for (i=0; i<m*2; i++) __setbit2(buf2,i,1-__getbit2(buf2,i));
666 //selects3 * lasts3=NULL;
670 int selects3_select(selects3 *select, int i) {
675 printf("ERROR: m=%d i=%d\n",select->m,i);
680 if (i == 0) return -1;
683 /*if(select->lasti==(uint)i-1) {
684 while(!__getbit2(select->sd1->buf,++select->lasts));
687 select->lasts = selectd2_select(select->sd1,i,1);
690 //lasts3 = select; */
691 x = selectd2_select1(select->sd1,i) - (i-1);
692 //x = (select->lasts-(i-1)) << d;
694 x += __getbits(select->low,(i-1)*d,d);
698 void pr_byte(FILE* fp, uchar b)
701 for(int i = 0; i < 8; i++){
702 fprintf(stderr, "%i", __getbit2(buff, i));
706 int selects3_selectnext(selects3 *select, int i) {
707 //return selects3_select(select,selects3_rank(select,i)+1);
716 y = selectd2_select0(select->sd0,ii)+1;
726 if (((z << r) & 0x80) == 0) {
731 w = __getbits(q,xoffset,d);
734 if (__getbit2(select->hi,((y << 3)+r))) k2 ++;
745 if(__getbit2(select->hi,( (y << 3)+r))) k2++;
753 if(x==select->m) return (uint)-1;
758 uint mask = ~(0xffu << (8*sizeof(uint) - 8));
759 uint tmp = (select->hi[y] << ((8*sizeof(uint) - 8)+r)) | mask;
760 uint c_incr = __builtin_clz(tmp);
765 uchar * pp = &(select->hi[c >> 3]);
772 c += __builtin_clz(*pp) - 24;
777 return __getbits(q,xoffset,d)+((c)<<d);
780 int selects3_rank(selects3 *select, int i) {
792 y = selectd2_select0(select->sd0, ii)+1;
804 if (((z << r) & 0x80) == 0) return x;
806 w = __getbits(q, xoffset, d);
808 if (w >= j) return x + (w == j);