8 #define min(x,y) ((x)<(y)?(x):(y))
12 #define max(x,y) ((x)>(y)?(x):(y))
20 #define SBid(i) ((i)>>logSB)
21 #define SBfirst(i) ((i) & (~(SB-1)))
22 #define SBlast(i) ((i) | (SB-1))
24 #define MBid(i) ((i)>>logMB)
25 #define MBfirst(i) ((i) & (~(MB-1)))
26 #define MBlast(i) ((i) | (MB-1))
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 // depth(bp *b, int s)
69 // returns the depth of s
70 // The root node has depth 1
71 ///////////////////////////////////////////
72 int depth(bp *b, int s)
76 d = 2 * darray_rank(b->da,s) - (s+1);
78 if (d != naive_depth(b,s)) {
82 //printf("depth(%d)=%d\n",s,d);
87 int fast_depth(bp *b, int s)
94 if ((s & (RRR-1)) != 0) {
95 //printf("fast_depth:warning s=%d\n",s);
99 //d = 2 * (da->rl[s>>logR] + da->rm[s>>logRR] + da->rs[s>>logRRR]) - s;
101 r = da->rl[s>>logR] + da->rm[s>>logRR];
102 j = (s>>logRRR) & (RR/RRR-1);
104 r += da->rs[((s>>logRR)<<(logRR-logRRR))+j-1];
112 int search_SB_r(bp *b, int i, int rel)
118 il = min((SBid(i) + 1) << logSB,n);
126 w = (x >> (D-ETW)) & ((1<<ETW)-1);
127 if (rel >= -ETW && rel <= ETW) {
128 r = fwdtbl[((rel+ETW)<<ETW)+w];
130 if (i+r >= n) return NOTFOUND;
135 rel -= 2*popcount(w)-r;
144 int search_MB_r(bp *b, int i, int td)
153 il = min((MBid(i) + 1) << logMB,n);
154 for ( ; i < il; i+=SB) {
158 d = fast_depth(b,i-1);
160 m = d + b->sm[SBid(i)] - SB;
161 M = d + b->sM[SBid(i)] - 1;
162 if (m <= td && td <= M) {
163 return search_SB_r(b,i,td-d);
166 if (i >= n) return NOTFOUND;
170 ///////////////////////////////////////////
171 // fwd_excess(bp *b,int s, int rel)
172 // find the leftmost value depth(s)+rel to the right of s (exclusive)
173 ///////////////////////////////////////////
174 int fwd_excess(bp *b,int s, int rel)
185 d = search_SB_r(b,i,rel);
186 if (d >= NOTFOUND) return d;
188 i = min((SBid(i) + 1) << logSB, n);
189 td = depth(b,s) + rel;
190 d = search_MB_r(b,i,td);
191 if (d >= NOTFOUND) return d;
203 if (m <= td && td <= M) {
208 if (!(m <= td && td <= M)) i++;
213 return search_MB_r(b,i,td);
223 int degree_SB_slow(bp *b, int i, int t, int rel, int *ans, int ith)
230 il = min((SBid(i) + 1) << logSB,n);
234 if (getbit(b->B,i)==OP) {
239 if (d < rel) { // reached the end
247 if (d == rel) { // found the same depth
260 int degree_SB(bp *b, int i, int t, int rel, int *ans, int ith)
269 il = min((SBid(i) + 1) << logSB,n);
279 w = (x >> (D-ETW)) & ((1<<ETW)-1);
281 if (j < ETW || il-i < ETW) {
282 r = max(ETW-j,ETW-(il-i));
285 v = minmaxtbl_v[0][w | w2];
289 for (r = 0; r < ETW; r++) {
307 r = childtbl2[rel-d+ETW][ith-1][w];
315 r = ETW-1-minmaxtbl_i[0][w | w2];
317 deg += degtbl2[((rel-d+ETW)<<ETW) + (w & (~w2))];
326 *ans = i + childtbl[((ith-1)<<ETW) + (w | w2)];
334 d += 2*popcount(w)-r;
345 int degree_MB(bp *b, int i, int t, int td, int *ans,int ith)
356 il = min((MBid(i) + 1) << logMB,n);
358 for ( ; i+SB-1 < il; i+=SB) {
362 d = fast_depth(b,i-1);
364 m = d + b->sm[SBid(i)] - SB;
366 r = degree_SB(b,i,n,td-d,°tmp,ith);
368 if (r == NOTFOUND) return NOTFOUND;
378 if (ith <= b->sd[SBid(i)]) break;
379 ith -= b->sd[SBid(i)];
381 deg += b->sd[SBid(i)];
388 d = fast_depth(b,i-1);
390 r = degree_SB(b,i,n,td-d,°tmp,ith);
392 if (r == NOTFOUND) return NOTFOUND;
402 if (i >= n) return END;
406 static int partition_range(int s,int t)
410 printf("partition [%d,%d] => ",s,t);
415 printf("[%d,%d] ",s,s+h-1);
425 printf("[%d,%d] ",s,s+h-1);
436 ///////////////////////////////////////////
437 // fast_degree(bp *b,int s, int t, int ith)
438 // returns the number of children of s, to the left of t
439 // returns the position of (ith)-th child of s if (ith > 0)
440 ///////////////////////////////////////////
441 int fast_degree(bp *b,int s, int t, int ith)
457 if (i != SBfirst(i)) {
458 d = degree_SB(b,i,n,0,°tmp,ith);
460 if (d == NOTFOUND) return -1;
461 if (d == FOUND) return degtmp;
464 if (d == END) return degtmp;
470 i = SBid(i+SB-1) << logSB;
472 if (i != MBfirst(i)) {
473 d = degree_MB(b,i,n,td,°tmp,ith);
475 if (d == NOTFOUND) return -1;
476 if (d == FOUND) return degtmp;
491 tm = MBid((n-1)+1)-1; // the rightmost MB fully contained in [0,n-1]
494 sm += m_ofs; tm += m_ofs;
495 for (i=sm; i<=tm; i++) {
499 if (b->mm[i] == td) {
501 if (ith <= b->md[i]) break;
510 tm = MBid((n-1)+1)-1; // the rightmost MB fully contained in [0,n-1]
513 sm += m_ofs; tm += m_ofs;
516 //partition_range(sm,tm);
518 //printf("partition [%d,%d] => ",sm,tm);
523 //printf("[%d,%d] ",sm,sm+h-1);
529 if (b->mm[j] == td) {
531 if (ith <= b->md[j]) {
542 if (sm+h > tm) break;
548 //printf("[%d,%d] ",sm,sm+h-1);
551 if (b->mm[j] >= td) {
552 if (b->mm[j] == td) {
553 if (ith > b->md[j]) {
564 if (b->mm[j] >= td) {
565 if (b->mm[j] == td) {
583 d = degree_MB(b,ss,n,td,°tmp,ith);
585 if (d == NOTFOUND) return -1;
586 if (d == FOUND) return degtmp;
589 if (d == END) return deg;
593 printf("degree: ???\n");
598 int search_SB_l(bp *b, int i, int rel)
611 w = x & ((1<<ETW)-1);
612 if (rel >= -ETW && rel <= ETW) {
613 r = bwdtbl[((rel+ETW)<<ETW)+w];
615 if (i-r < 0) return NOTFOUND;
620 rel += 2*popcount(w)-r;
627 if (i < 0) return NOTFOUND;
631 int search_MB_l(bp *b, int i, int td)
638 if (i % SB != SB-1) {
639 printf("search_MB_l:error!!! i=%d SB=%d\n",i,i%SB);
645 for ( ; i >= il; i-=SB) {
649 d = fast_depth(b,i-SB);
651 m = d + b->sm[SBid(i)] - SB;
652 M = d + b->sM[SBid(i)] - 1;
653 if (m <= td && td <= M) {
659 if (d == td) return i;
660 return search_SB_l(b,i,td-d);
666 ///////////////////////////////////////////
667 // bwd_excess(bp *b,int s, int rel)
668 // find the rightmost value depth(s)+rel to the left of s (exclusive)
669 ///////////////////////////////////////////
670 int bwd_excess(bp *b,int s, int rel)
680 d = search_SB_l(b,i,rel);
681 if (d >= NOTFOUND) return d;
685 td = depth(b,s) + rel;
687 d = search_MB_l(b,i,td);
688 if (d >= NOTFOUND) return d;
691 i = (s>>logMB) + m_ofs;
697 if (m <= td && td <= M) break;
702 if (td == 0) return -1;
703 else return NOTFOUND;
710 if (!(m <= td && td <= M)) i--;
713 i = ((i+1)<<logMB)-1;
715 d = search_MB_l(b,i,td);
716 if (d >= NOTFOUND) return d;
719 printf("bwd_excess: ???\n");
724 int rmq_SB(bp *b, int s, int t, int opt, int *dm)
733 lr = 0; if (opt & OPT_RIGHT) lr = 1;
734 op = opt & (OPT_RIGHT | OPT_MAX);
747 w = (x >> (D-ETW)) & ((1<<ETW)-1);
749 if (j < ETW || t-i < ETW-1) {
750 r = max(ETW-j,ETW-1-(t-i));
755 v = minmaxtbl_v[op][w & (~w2)];
756 if (d + v + lr > ds) {
758 is = i + minmaxtbl_i[op][w & (~w2)];
761 v = minmaxtbl_v[op][w | w2];
762 if (d + v < ds +lr) {
764 is = i + minmaxtbl_i[op][w | w2];
769 d += 2*popcount(w)-r;
777 if (getbit(b->B,i)==OP) {
786 if (!(op & OPT_MAX)) {
799 int rmq_MB(bp *b, int s, int t, int opt, int *dm)
805 lr = 0; if (opt & OPT_RIGHT) lr = 1;
808 for (i = s; i <= t; i++) {
810 d = depth(b,(i<<logSB)-1);
812 d = fast_depth(b,(i<<logSB)-1);
815 m = d + b->sM[i] - 1;
820 m = d + b->sm[i] - SB;
833 ///////////////////////////////////////////
834 // rmq(bp *b, int s, int t, int opt)
835 // returns the index of leftmost/rightmost minimum/maximum value
836 // in the range [s,t] (inclusive)
837 // returns the leftmost minimum if opt == 0
838 // the rightmost one if (opt & OPT_RIGHT)
839 // the maximum if (opt & OPT_MAX)
840 ///////////////////////////////////////////
841 int rmq(bp *b, int s, int t, int opt)
843 int ss, ts; // SB index of s and t
844 int sm, tm; // MB index of s and t
845 int ds; // current min value
846 int is; // current min index
847 int ys; // type of current min index
848 // 0: is is the index of min
849 // 1: is is the SB index
850 // 2: is is the MB index
856 lr = 0; if (opt & OPT_RIGHT) lr = 1;
859 if (s < 0 || t >= n || s > t) {
860 printf("rmq: error s=%d t=%d n=%d\n",s,t,n);
863 if (s == t) return s;
866 ////////////////////////////////////////////////////////////
867 // search the SB of s
868 ////////////////////////////////////////////////////////////
870 il = min(SBlast(s),t);
871 is = rmq_SB(b,s,il,opt,&dm);
872 if (il == t) { // scan reached the end of the range
875 ds = depth(b,s) + dm; ys = 0;
877 ////////////////////////////////////////////////////////////
878 // search the MB of s
879 ////////////////////////////////////////////////////////////
882 il = min(SBid(MBlast(s)),SBid(t)-1);
884 j = rmq_MB(b,ss,il,opt,&dm);
885 //if (dm < ds + lr) {
887 ds = dm; is = j; ys = 1;
890 ////////////////////////////////////////////////////////////
892 ////////////////////////////////////////////////////////////
900 sm += m_ofs; tm += m_ofs;
901 for (i=sm; i<=tm; i++) {
903 if (b->mM[i] + lr > ds) {
904 ds = b->mM[i]; is = i - m_ofs; ys = 2;
907 if (b->mm[i] < ds + lr) {
908 ds = b->mm[i]; is = i - m_ofs; ys = 2;
919 sm += m_ofs; tm += m_ofs;
922 if (b->mM[sm] + lr > ds) {
923 ds = b->mM[sm]; is = sm; ys = 2;
925 for (i=0; i<=h-2; i++) {
928 if (b->mM[j+1] + lr > ds) {
929 ds = b->mM[j+1]; is = j+1; ys = 2;
933 for (i=h-2; i>=0; i--) {
936 if (b->mM[j-1] + lr > ds) {
937 ds = b->mM[j-1]; is = j-1; ys = 2;
941 if (b->mM[tm] + lr > ds) {
942 ds = b->mM[tm]; is = tm; ys = 2;
947 if (b->mM[is+1] + lr > b->mM[is]) is++;
952 if (b->mm[sm] < ds + lr) {
953 ds = b->mm[sm]; is = sm; ys = 2;
955 for (i=0; i<=h-2; i++) {
958 if (b->mm[j+1] < ds + lr) {
959 ds = b->mm[j+1]; is = j+1; ys = 2;
963 for (i=h-2; i>=0; i--) {
966 if (b->mm[j-1] < ds + lr) {
967 ds = b->mm[j-1]; is = j-1; ys = 2;
971 if (b->mm[tm] < ds + lr) {
972 ds = b->mm[tm]; is = tm; ys = 2;
977 if (b->mm[is+1] < b->mm[is] + lr) is++;
986 ////////////////////////////////////////////////////////////
987 // search the MB of t
988 ////////////////////////////////////////////////////////////
991 ts = max(SBid(MBfirst(t)),SBid(s)+1);
992 il = SBid(SBfirst(t)-1);
994 j = rmq_MB(b,ts,il,opt,&dm);
995 //if (dm < ds + lr) {
997 ds = dm; is = j; ys = 1;
1000 ////////////////////////////////////////////////////////////
1001 // search the SB of t
1002 ////////////////////////////////////////////////////////////
1005 j = rmq_SB(b,i,t,opt,&dm);
1006 d = depth(b,i) + dm;
1007 if (opt & OPT_MAX) {
1009 ds = d; is = j; ys = 0;
1013 ds = d; is = j; ys = 0;
1017 ////////////////////////////////////////////////////////////
1019 ////////////////////////////////////////////////////////////
1022 ss = SBid(is << logMB);
1023 il = SBid(MBlast(is << logMB));
1024 if (opt & OPT_MAX) {
1029 j = rmq_MB(b,ss,il,opt,&dm);
1030 ds = dm; is = j; ys = 1;
1035 il = SBlast(is << logSB);
1036 is = rmq_SB(b,ss,il,opt,&dm);
1037 //ds = depth(b,ss) + dm; ys = 0;