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 pb getpat_preorder(pb *b)
23 pb getpat_postorder(pb *b)
32 w2 = (w1 << 1) + (b[1] >> (D-1));
37 pb getpat_inorder(pb *b)
41 w2 = (w1 << 1) + (b[1] >> (D-1));
46 pb getpat_dfuds_leaf(pb *b)
50 w2 = (w1 << 1) + (b[1] >> (D-1));
57 ///////////////////////////////////////////
58 // depth(bp *b, int s)
59 // returns the depth of s
60 // The root node has depth 1
61 ///////////////////////////////////////////
62 int depth(bp *b, int s)
66 d = 2 * darray_rank(b->da,s) - (s+1);
68 if (d != naive_depth(b,s)) {
72 //printf("depth(%d)=%d\n",s,d);
77 int fast_depth(bp *b, int s)
84 if ((s & (RRR-1)) != 0) {
85 //printf("fast_depth:warning s=%d\n",s);
89 //d = 2 * (da->rl[s>>logR] + da->rm[s>>logRR] + da->rs[s>>logRRR]) - s;
91 r = da->rl[s>>logR] + da->rm[s>>logRR];
92 j = (s>>logRRR) & (RR/RRR-1);
94 r += da->rs[((s>>logRR)<<(logRR-logRRR))+j-1];
102 int search_SB_r(bp *b, int i, int rel)
108 il = min((SBid(i) + 1) << logSB,n);
116 w = (x >> (D-ETW)) & ((1<<ETW)-1);
117 if (rel >= -ETW && rel <= ETW) {
118 r = fwdtbl[((rel+ETW)<<ETW)+w];
120 if (i+r >= n) return NOTFOUND;
125 rel -= 2*popCount[w]-r;
134 int search_MB_r(bp *b, int i, int td)
143 il = min((MBid(i) + 1) << logMB,n);
144 for ( ; i < il; i+=SB) {
148 d = fast_depth(b,i-1);
150 m = d + b->sm[SBid(i)] - SB;
151 M = d + b->sM[SBid(i)] - 1;
152 if (m <= td && td <= M) {
153 return search_SB_r(b,i,td-d);
156 if (i >= n) return NOTFOUND;
160 ///////////////////////////////////////////
161 // fwd_excess(bp *b,int s, int rel)
162 // find the leftmost value depth(s)+rel to the right of s (exclusive)
163 ///////////////////////////////////////////
164 int fwd_excess(bp *b,int s, int rel)
175 d = search_SB_r(b,i,rel);
176 if (d >= NOTFOUND) return d;
178 i = min((SBid(i) + 1) << logSB,n);
179 td = depth(b,s) + rel;
180 d = search_MB_r(b,i,td);
181 if (d >= NOTFOUND) return d;
183 if (i != SBfirst(i)) {
184 d = search_SB_r(b,i,rel);
185 if (d >= NOTFOUND) return d;
188 td = depth(b,s) + rel;
190 i = SBid(i+SB-1) << logSB;
192 if (i != MBfirst(i)) {
193 d = search_MB_r(b,i,td);
194 if (d >= NOTFOUND) return d;
205 if (m <= td && td <= M) break;
209 if (i == 0) return NOTFOUND;
215 if (!(m <= td && td <= M)) i++;
220 d = search_MB_r(b,i,td);
221 if (d >= NOTFOUND) return d;
224 printf("fwd_excess: ???\n");
230 int degree_SB_slow(bp *b, int i, int t, int rel, int *ans, int ith)
237 il = min((SBid(i) + 1) << logSB,n);
241 if (getbit(b->B,i)==OP) {
246 if (d < rel) { // reached the end
254 if (d == rel) { // found the same depth
267 int degree_SB(bp *b, int i, int t, int rel, int *ans, int ith)
276 il = min((SBid(i) + 1) << logSB,n);
286 w = (x >> (D-ETW)) & ((1<<ETW)-1);
288 if (j < ETW || il-i < ETW) {
289 r = max(ETW-j,ETW-(il-i));
292 v = minmaxtbl_v[0][w | w2];
296 for (r = 0; r < ETW; r++) {
314 r = childtbl2[rel-d+ETW][ith-1][w];
322 r = ETW-1-minmaxtbl_i[0][w | w2];
324 deg += degtbl2[((rel-d+ETW)<<ETW) + (w & (~w2))];
333 *ans = i + childtbl[((ith-1)<<ETW) + (w | w2)];
341 d += 2*popCount[w]-r;
352 int degree_MB(bp *b, int i, int t, int td, int *ans,int ith)
363 il = min((MBid(i) + 1) << logMB,n);
365 for ( ; i+SB-1 < il; i+=SB) {
369 d = fast_depth(b,i-1);
371 m = d + b->sm[SBid(i)] - SB;
373 r = degree_SB(b,i,n,td-d,°tmp,ith);
375 if (r == NOTFOUND) return NOTFOUND;
385 if (ith <= b->sd[SBid(i)]) break;
386 ith -= b->sd[SBid(i)];
388 deg += b->sd[SBid(i)];
395 d = fast_depth(b,i-1);
397 r = degree_SB(b,i,n,td-d,°tmp,ith);
399 if (r == NOTFOUND) return NOTFOUND;
409 if (i >= n) return END;
413 static int partition_range(int s,int t)
417 printf("partition [%d,%d] => ",s,t);
422 printf("[%d,%d] ",s,s+h-1);
432 printf("[%d,%d] ",s,s+h-1);
443 ///////////////////////////////////////////
444 // fast_degree(bp *b,int s, int t, int ith)
445 // returns the number of children of s, to the left of t
446 // returns the position of (ith)-th child of s if (ith > 0)
447 ///////////////////////////////////////////
448 int fast_degree(bp *b,int s, int t, int ith)
464 if (i != SBfirst(i)) {
465 d = degree_SB(b,i,n,0,°tmp,ith);
467 if (d == NOTFOUND) return -1;
468 if (d == FOUND) return degtmp;
471 if (d == END) return degtmp;
477 i = SBid(i+SB-1) << logSB;
479 if (i != MBfirst(i)) {
480 d = degree_MB(b,i,n,td,°tmp,ith);
482 if (d == NOTFOUND) return -1;
483 if (d == FOUND) return degtmp;
498 tm = MBid((n-1)+1)-1; // the rightmost MB fully contained in [0,n-1]
501 sm += m_ofs; tm += m_ofs;
502 for (i=sm; i<=tm; i++) {
506 if (b->mm[i] == td) {
508 if (ith <= b->md[i]) break;
517 tm = MBid((n-1)+1)-1; // the rightmost MB fully contained in [0,n-1]
520 sm += m_ofs; tm += m_ofs;
523 //partition_range(sm,tm);
525 //printf("partition [%d,%d] => ",sm,tm);
530 //printf("[%d,%d] ",sm,sm+h-1);
536 if (b->mm[j] == td) {
538 if (ith <= b->md[j]) {
549 if (sm+h > tm) break;
555 //printf("[%d,%d] ",sm,sm+h-1);
558 if (b->mm[j] >= td) {
559 if (b->mm[j] == td) {
560 if (ith > b->md[j]) {
571 if (b->mm[j] >= td) {
572 if (b->mm[j] == td) {
590 d = degree_MB(b,ss,n,td,°tmp,ith);
592 if (d == NOTFOUND) return -1;
593 if (d == FOUND) return degtmp;
596 if (d == END) return deg;
600 printf("degree: ???\n");
605 int search_SB_l(bp *b, int i, int rel)
618 w = x & ((1<<ETW)-1);
619 if (rel >= -ETW && rel <= ETW) {
620 r = bwdtbl[((rel+ETW)<<ETW)+w];
622 if (i-r < 0) return NOTFOUND;
627 rel += 2*popCount[w]-r;
634 if (i < 0) return NOTFOUND;
638 int search_MB_l(bp *b, int i, int td)
645 if (i % SB != SB-1) {
646 printf("search_MB_l:error!!! i=%d SB=%d\n",i,i%SB);
652 for ( ; i >= il; i-=SB) {
656 d = fast_depth(b,i-SB);
658 m = d + b->sm[SBid(i)] - SB;
659 M = d + b->sM[SBid(i)] - 1;
660 if (m <= td && td <= M) {
666 if (d == td) return i;
667 return search_SB_l(b,i,td-d);
673 ///////////////////////////////////////////
674 // bwd_excess(bp *b,int s, int rel)
675 // find the rightmost value depth(s)+rel to the left of s (exclusive)
676 ///////////////////////////////////////////
677 int bwd_excess(bp *b,int s, int rel)
687 d = search_SB_l(b,i,rel);
688 if (d >= NOTFOUND) return d;
692 td = depth(b,s) + rel;
694 d = search_MB_l(b,i,td);
695 if (d >= NOTFOUND) return d;
698 i = (s>>logMB) + m_ofs;
704 if (m <= td && td <= M) break;
709 if (td == 0) return -1;
710 else return NOTFOUND;
717 if (!(m <= td && td <= M)) i--;
720 i = ((i+1)<<logMB)-1;
722 d = search_MB_l(b,i,td);
723 if (d >= NOTFOUND) return d;
726 printf("bwd_excess: ???\n");
731 int rmq_SB(bp *b, int s, int t, int opt, int *dm)
740 lr = 0; if (opt & OPT_RIGHT) lr = 1;
741 op = opt & (OPT_RIGHT | OPT_MAX);
754 w = (x >> (D-ETW)) & ((1<<ETW)-1);
756 if (j < ETW || t-i < ETW-1) {
757 r = max(ETW-j,ETW-1-(t-i));
762 v = minmaxtbl_v[op][w & (~w2)];
763 if (d + v + lr > ds) {
765 is = i + minmaxtbl_i[op][w & (~w2)];
768 v = minmaxtbl_v[op][w | w2];
769 if (d + v < ds +lr) {
771 is = i + minmaxtbl_i[op][w | w2];
776 d += 2*popCount[w]-r;
784 if (getbit(b->B,i)==OP) {
793 if (!(op & OPT_MAX)) {
806 int rmq_MB(bp *b, int s, int t, int opt, int *dm)
812 lr = 0; if (opt & OPT_RIGHT) lr = 1;
815 for (i = s; i <= t; i++) {
817 d = depth(b,(i<<logSB)-1);
819 d = fast_depth(b,(i<<logSB)-1);
822 m = d + b->sM[i] - 1;
827 m = d + b->sm[i] - SB;
840 ///////////////////////////////////////////
841 // rmq(bp *b, int s, int t, int opt)
842 // returns the index of leftmost/rightmost minimum/maximum value
843 // in the range [s,t] (inclusive)
844 // returns the leftmost minimum if opt == 0
845 // the rightmost one if (opt & OPT_RIGHT)
846 // the maximum if (opt & OPT_MAX)
847 ///////////////////////////////////////////
848 int rmq(bp *b, int s, int t, int opt)
850 int ss, ts; // SB index of s and t
851 int sm, tm; // MB index of s and t
852 int ds; // current min value
853 int is; // current min index
854 int ys; // type of current min index
855 // 0: is is the index of min
856 // 1: is is the SB index
857 // 2: is is the MB index
863 lr = 0; if (opt & OPT_RIGHT) lr = 1;
866 if (s < 0 || t >= n || s > t) {
867 printf("rmq: error s=%d t=%d n=%d\n",s,t,n);
870 if (s == t) return s;
873 ////////////////////////////////////////////////////////////
874 // search the SB of s
875 ////////////////////////////////////////////////////////////
877 il = min(SBlast(s),t);
878 is = rmq_SB(b,s,il,opt,&dm);
879 if (il == t) { // scan reached the end of the range
882 ds = depth(b,s) + dm; ys = 0;
884 ////////////////////////////////////////////////////////////
885 // search the MB of s
886 ////////////////////////////////////////////////////////////
889 il = min(SBid(MBlast(s)),SBid(t)-1);
891 j = rmq_MB(b,ss,il,opt,&dm);
892 //if (dm < ds + lr) {
894 ds = dm; is = j; ys = 1;
897 ////////////////////////////////////////////////////////////
899 ////////////////////////////////////////////////////////////
907 sm += m_ofs; tm += m_ofs;
908 for (i=sm; i<=tm; i++) {
910 if (b->mM[i] + lr > ds) {
911 ds = b->mM[i]; is = i - m_ofs; ys = 2;
914 if (b->mm[i] < ds + lr) {
915 ds = b->mm[i]; is = i - m_ofs; ys = 2;
926 sm += m_ofs; tm += m_ofs;
929 if (b->mM[sm] + lr > ds) {
930 ds = b->mM[sm]; is = sm; ys = 2;
932 for (i=0; i<=h-2; i++) {
935 if (b->mM[j+1] + lr > ds) {
936 ds = b->mM[j+1]; is = j+1; ys = 2;
940 for (i=h-2; i>=0; i--) {
943 if (b->mM[j-1] + lr > ds) {
944 ds = b->mM[j-1]; is = j-1; ys = 2;
948 if (b->mM[tm] + lr > ds) {
949 ds = b->mM[tm]; is = tm; ys = 2;
954 if (b->mM[is+1] + lr > b->mM[is]) is++;
959 if (b->mm[sm] < ds + lr) {
960 ds = b->mm[sm]; is = sm; ys = 2;
962 for (i=0; i<=h-2; i++) {
965 if (b->mm[j+1] < ds + lr) {
966 ds = b->mm[j+1]; is = j+1; ys = 2;
970 for (i=h-2; i>=0; i--) {
973 if (b->mm[j-1] < ds + lr) {
974 ds = b->mm[j-1]; is = j-1; ys = 2;
978 if (b->mm[tm] < ds + lr) {
979 ds = b->mm[tm]; is = tm; ys = 2;
984 if (b->mm[is+1] < b->mm[is] + lr) is++;
993 ////////////////////////////////////////////////////////////
994 // search the MB of t
995 ////////////////////////////////////////////////////////////
998 ts = max(SBid(MBfirst(t)),SBid(s)+1);
999 il = SBid(SBfirst(t)-1);
1001 j = rmq_MB(b,ts,il,opt,&dm);
1002 //if (dm < ds + lr) {
1004 ds = dm; is = j; ys = 1;
1007 ////////////////////////////////////////////////////////////
1008 // search the SB of t
1009 ////////////////////////////////////////////////////////////
1012 j = rmq_SB(b,i,t,opt,&dm);
1013 d = depth(b,i) + dm;
1014 if (opt & OPT_MAX) {
1016 ds = d; is = j; ys = 0;
1020 ds = d; is = j; ys = 0;
1024 ////////////////////////////////////////////////////////////
1026 ////////////////////////////////////////////////////////////
1029 ss = SBid(is << logMB);
1030 il = SBid(MBlast(is << logMB));
1031 if (opt & OPT_MAX) {
1036 j = rmq_MB(b,ss,il,opt,&dm);
1037 ds = dm; is = j; ys = 1;
1042 il = SBlast(is << logSB);
1043 is = rmq_SB(b,ss,il,opt,&dm);
1044 //ds = depth(b,ss) + dm; ys = 0;