10 #define SBid(i) ((i)>>logSB)
11 #define SBfirst(i) ((i) & (~(SB-1)))
12 #define SBlast(i) ((i) | (SB-1))
14 #define MBid(i) ((i)>>logMB)
15 #define MBfirst(i) ((i) & (~(MB-1)))
16 #define MBlast(i) ((i) | (MB-1))
18 static int min(int a, int b)
20 return (a <= b) ? a : b;
23 static int max(int a, int b)
25 return (a >= b) ? a : b;
28 pb getpat_preorder(pb *b)
33 pb getpat_postorder(pb *b)
42 w2 = (w1 << 1) + (b[1] >> (D-1));
47 pb getpat_inorder(pb *b)
51 w2 = (w1 << 1) + (b[1] >> (D-1));
56 pb getpat_dfuds_leaf(pb *b)
60 w2 = (w1 << 1) + (b[1] >> (D-1));
67 ///////////////////////////////////////////
68 // bp_depth(bp *b, int s)
69 // returns the depth of s
70 // The root node has depth 1
71 ///////////////////////////////////////////
72 int bp_depth(bp *b, int s)
76 d = 2 * bp_darray_rank(b->da,s) - (s+1);
80 int fast_depth(bp *b, int s)
87 if ((s & (RRR-1)) != 0) {
88 //printf("fast_depth:warning s=%d\n",s);
92 //d = 2 * (da->rl[s>>logR] + da->rm[s>>logRR] + da->rs[s>>logRRR]) - s;
94 r = da->rl[s>>logR] + da->rm[s>>logRR];
95 j = (s>>logRRR) & (RR/RRR-1);
97 r += da->rs[((s>>logRR)<<(logRR-logRRR))+j-1];
105 int search_SB_r(bp *b, int i, int rel)
111 il = min((SBid(i) + 1) << logSB, n);
119 w = (x >> (D-ETW)) & ((1<<ETW)-1);
120 if (rel >= -ETW && rel <= ETW) {
121 r = fwdtbl[((rel+ETW)<<ETW)+w];
123 if (i+r >= n) return NOTFOUND;
128 rel -= (popcount(w) << 1)-r;
137 int search_MB_r(bp *b, int i, int td)
146 il = min((MBid(i) + 1) << logMB, n);
147 for ( ; i < il; i+=SB) {
151 d = fast_depth(b,i-1);
153 m = d + b->sm[SBid(i)] - SB;
154 M = d + b->sM[SBid(i)] - 1;
155 if (m <= td && td <= M) {
156 return search_SB_r(b,i,td-d);
159 if (i >= n) return NOTFOUND;
163 ///////////////////////////////////////////
164 // bp_fwd_excess(bp *b,int s, int rel)
165 // find the leftmost value depth(s)+rel to the right of s (exclusive)
166 ///////////////////////////////////////////
167 int bp_fwd_excess(bp *b,int s, int rel)
179 d = search_SB_r(b,i,rel);
180 if (d >= NOTFOUND) return d;
182 i = min((SBid(i) + 1) << logSB, n);
183 td = bp_depth(b,s) + rel;
184 d = search_MB_r(b,i,td);
185 if (d >= NOTFOUND) return d;
197 if (m <= td && td <= M) {
202 if (!(m <= td && td <= M)) i++;
207 return search_MB_r(b,i,td);
217 int degree_SB_slow(bp *b, int i, int t, int rel, int *ans, int ith)
224 il = min((SBid(i) + 1) << logSB,n);
228 if (bp_getbit(b->B,i)==OP) {
233 if (d < rel) { // reached the end
241 if (d == rel) { // found the same depth
254 int degree_SB(bp *b, int i, int t, int rel, int *ans, int ith)
263 il = min((SBid(i) + 1) << logSB,n);
273 w = (x >> (D-ETW)) & ((1<<ETW)-1);
275 if (j < ETW || il-i < ETW) {
276 r = max(ETW-j,ETW-(il-i));
279 v = minmaxtbl_v[0][w | w2];
283 for (r = 0; r < ETW; r++) {
301 r = childtbl2[rel-d+ETW][ith-1][w];
309 r = ETW-1-minmaxtbl_i[0][w | w2];
311 deg += degtbl2[((rel-d+ETW)<<ETW) + (w & (~w2))];
320 *ans = i + childtbl[((ith-1)<<ETW) + (w | w2)];
328 d += 2*popcount(w)-r;
339 int degree_MB(bp *b, int i, int t, int td, int *ans,int ith)
350 il = min((MBid(i) + 1) << logMB,n);
352 for ( ; i+SB-1 < il; i+=SB) {
356 d = fast_depth(b,i-1);
358 m = d + b->sm[SBid(i)] - SB;
360 r = degree_SB(b,i,n,td-d,°tmp,ith);
362 if (r == NOTFOUND) return NOTFOUND;
372 if (ith <= b->sd[SBid(i)]) break;
373 ith -= b->sd[SBid(i)];
375 deg += b->sd[SBid(i)];
382 d = fast_depth(b,i-1);
384 r = degree_SB(b,i,n,td-d,°tmp,ith);
386 if (r == NOTFOUND) return NOTFOUND;
396 if (i >= n) return END;
400 static void partition_range(int s,int t)
404 printf("partition [%d,%d] => ",s,t);
409 printf("[%d,%d] ",s,s+h-1);
419 printf("[%d,%d] ",s,s+h-1);
430 ///////////////////////////////////////////
431 // bp_fast_degree(bp *b,int s, int t, int ith)
432 // returns the number of children of s, to the left of t
433 // returns the position of (ith)-th child of s if (ith > 0)
434 ///////////////////////////////////////////
435 int bp_fast_degree(bp *b,int s, int t, int ith)
451 if (i != SBfirst(i)) {
452 d = degree_SB(b,i,n,0,°tmp,ith);
454 if (d == NOTFOUND) return -1;
455 if (d == FOUND) return degtmp;
458 if (d == END) return degtmp;
464 i = SBid(i+SB-1) << logSB;
466 if (i != MBfirst(i)) {
467 d = degree_MB(b,i,n,td,°tmp,ith);
469 if (d == NOTFOUND) return -1;
470 if (d == FOUND) return degtmp;
485 tm = MBid((n-1)+1)-1; // the rightmost MB fully contained in [0,n-1]
488 sm += m_ofs; tm += m_ofs;
489 for (i=sm; i<=tm; i++) {
493 if (b->mm[i] == td) {
495 if (ith <= b->md[i]) break;
504 tm = MBid((n-1)+1)-1; // the rightmost MB fully contained in [0,n-1]
507 sm += m_ofs; tm += m_ofs;
510 //partition_range(sm,tm);
512 //printf("partition [%d,%d] => ",sm,tm);
517 //printf("[%d,%d] ",sm,sm+h-1);
523 if (b->mm[j] == td) {
525 if (ith <= b->md[j]) {
536 if (sm+h > tm) break;
542 //printf("[%d,%d] ",sm,sm+h-1);
545 if (b->mm[j] >= td) {
546 if (b->mm[j] == td) {
547 if (ith > b->md[j]) {
558 if (b->mm[j] >= td) {
559 if (b->mm[j] == td) {
577 d = degree_MB(b,ss,n,td,°tmp,ith);
579 if (d == NOTFOUND) return -1;
580 if (d == FOUND) return degtmp;
583 if (d == END) return deg;
587 printf("degree: ???\n");
592 int search_SB_l(bp *b, int i, int rel)
605 w = x & ((1<<ETW)-1);
606 if (rel >= -ETW && rel <= ETW) {
607 r = bwdtbl[((rel+ETW)<<ETW)+w];
609 if (i-r < 0) return NOTFOUND;
614 rel += 2*popcount(w)-r;
621 if (i < 0) return NOTFOUND;
625 int search_MB_l(bp *b, int i, int td)
632 if (i % SB != SB-1) {
633 printf("search_MB_l:error!!! i=%d SB=%d\n",i,i%SB);
639 for ( ; i >= il; i-=SB) {
641 d = bp_depth(b,i-SB);
643 d = fast_depth(b,i-SB);
645 m = d + b->sm[SBid(i)] - SB;
646 M = d + b->sM[SBid(i)] - 1;
647 if (m <= td && td <= M) {
653 if (d == td) return i;
654 return search_SB_l(b,i,td-d);
660 ///////////////////////////////////////////
661 // bwd_excess(bp *b,int s, int rel)
662 // find the rightmost value depth(s)+rel to the left of s (exclusive)
663 ///////////////////////////////////////////
664 int bp_bwd_excess(bp *b,int s, int rel)
674 d = search_SB_l(b,i,rel);
675 if (d >= NOTFOUND) return d;
679 td = bp_depth(b,s) + rel;
681 d = search_MB_l(b,i,td);
682 if (d >= NOTFOUND) return d;
685 i = (s>>logMB) + m_ofs;
691 if (m <= td && td <= M) break;
696 if (td == 0) return -1;
697 else return NOTFOUND;
704 if (!(m <= td && td <= M)) i--;
707 i = ((i+1)<<logMB)-1;
709 d = search_MB_l(b,i,td);
710 if (d >= NOTFOUND) return d;
713 printf("bwd_excess: ???\n");
718 int rmq_SB(bp *b, int s, int t, int opt, int *dm)
727 lr = 0; if (opt & OPT_RIGHT) lr = 1;
728 op = opt & (OPT_RIGHT | OPT_MAX);
741 w = (x >> (D-ETW)) & ((1<<ETW)-1);
743 if (j < ETW || t-i < ETW-1) {
744 r = max(ETW-j,ETW-1-(t-i));
749 v = minmaxtbl_v[op][w & (~w2)];
750 if (d + v + lr > ds) {
752 is = i + minmaxtbl_i[op][w & (~w2)];
755 v = minmaxtbl_v[op][w | w2];
756 if (d + v < ds +lr) {
758 is = i + minmaxtbl_i[op][w | w2];
763 d += 2*popcount(w)-r;
771 if (bp_getbit(b->B,i)==OP) {
780 if (!(op & OPT_MAX)) {
793 int rmq_MB(bp *b, int s, int t, int opt, int *dm)
799 lr = 0; if (opt & OPT_RIGHT) lr = 1;
802 for (i = s; i <= t; i++) {
804 d = bp_depth(b,(i<<logSB)-1);
806 d = fast_depth(b,(i<<logSB)-1);
809 m = d + b->sM[i] - 1;
814 m = d + b->sm[i] - SB;
827 ///////////////////////////////////////////
828 // bp_rmq(bp *b, int s, int t, int opt)
829 // returns the index of leftmost/rightmost minimum/maximum value
830 // in the range [s,t] (inclusive)
831 // returns the leftmost minimum if opt == 0
832 // the rightmost one if (opt & OPT_RIGHT)
833 // the maximum if (opt & OPT_MAX)
834 ///////////////////////////////////////////
835 int bp_rmq(bp *b, int s, int t, int opt)
837 int ss, ts; // SB index of s and t
838 int sm, tm; // MB index of s and t
839 int ds; // current min value
840 int is; // current min index
841 int ys; // type of current min index
842 // 0: is is the index of min
843 // 1: is is the SB index
844 // 2: is is the MB index
850 lr = 0; if (opt & OPT_RIGHT) lr = 1;
853 if (s < 0 || t >= n || s > t) {
854 printf("rmq: error s=%d t=%d n=%d\n",s,t,n);
857 if (s == t) return s;
860 ////////////////////////////////////////////////////////////
861 // search the SB of s
862 ////////////////////////////////////////////////////////////
864 il = min(SBlast(s),t);
865 is = rmq_SB(b,s,il,opt,&dm);
866 if (il == t) { // scan reached the end of the range
869 ds = bp_depth(b,s) + dm; ys = 0;
871 ////////////////////////////////////////////////////////////
872 // search the MB of s
873 ////////////////////////////////////////////////////////////
876 il = min(SBid(MBlast(s)),SBid(t)-1);
878 j = rmq_MB(b,ss,il,opt,&dm);
879 //if (dm < ds + lr) {
881 ds = dm; is = j; ys = 1;
884 ////////////////////////////////////////////////////////////
886 ////////////////////////////////////////////////////////////
894 sm += m_ofs; tm += m_ofs;
895 for (i=sm; i<=tm; i++) {
897 if (b->mM[i] + lr > ds) {
898 ds = b->mM[i]; is = i - m_ofs; ys = 2;
901 if (b->mm[i] < ds + lr) {
902 ds = b->mm[i]; is = i - m_ofs; ys = 2;
913 sm += m_ofs; tm += m_ofs;
916 if (b->mM[sm] + lr > ds) {
917 ds = b->mM[sm]; is = sm; ys = 2;
919 for (i=0; i<=h-2; i++) {
922 if (b->mM[j+1] + lr > ds) {
923 ds = b->mM[j+1]; is = j+1; ys = 2;
927 for (i=h-2; i>=0; i--) {
930 if (b->mM[j-1] + lr > ds) {
931 ds = b->mM[j-1]; is = j-1; ys = 2;
935 if (b->mM[tm] + lr > ds) {
936 ds = b->mM[tm]; is = tm; ys = 2;
941 if (b->mM[is+1] + lr > b->mM[is]) is++;
946 if (b->mm[sm] < ds + lr) {
947 ds = b->mm[sm]; is = sm; ys = 2;
949 for (i=0; i<=h-2; i++) {
952 if (b->mm[j+1] < ds + lr) {
953 ds = b->mm[j+1]; is = j+1; ys = 2;
957 for (i=h-2; i>=0; i--) {
960 if (b->mm[j-1] < ds + lr) {
961 ds = b->mm[j-1]; is = j-1; ys = 2;
965 if (b->mm[tm] < ds + lr) {
966 ds = b->mm[tm]; is = tm; ys = 2;
971 if (b->mm[is+1] < b->mm[is] + lr) is++;
980 ////////////////////////////////////////////////////////////
981 // search the MB of t
982 ////////////////////////////////////////////////////////////
985 ts = max(SBid(MBfirst(t)),SBid(s)+1);
986 il = SBid(SBfirst(t)-1);
988 j = rmq_MB(b,ts,il,opt,&dm);
989 //if (dm < ds + lr) {
991 ds = dm; is = j; ys = 1;
994 ////////////////////////////////////////////////////////////
995 // search the SB of t
996 ////////////////////////////////////////////////////////////
999 j = rmq_SB(b,i,t,opt,&dm);
1000 d = bp_depth(b,i) + dm;
1001 if (opt & OPT_MAX) {
1003 ds = d; is = j; ys = 0;
1007 ds = d; is = j; ys = 0;
1011 ////////////////////////////////////////////////////////////
1013 ////////////////////////////////////////////////////////////
1016 ss = SBid(is << logMB);
1017 il = SBid(MBlast(is << logMB));
1018 if (opt & OPT_MAX) {
1023 j = rmq_MB(b,ss,il,opt,&dm);
1024 ds = dm; is = j; ys = 1;
1029 il = SBlast(is << logSB);
1030 is = rmq_SB(b,ss,il,opt,&dm);
1031 //ds = bp_depth(b,ss) + dm; ys = 0;