return (__type*)p; \
}
+#define __KRMQ_RMQ(suf, __scope, __type, __head, __cmp, __lt2) \
+ __scope __type *krmq_rmq_##suf(const __type *root, const __type *lo, const __type *up) { /* CLOSED interval */ \
+ const __type *p = root, *path[2][KRMQ_MAX_DEPTH], *min; \
+ int plen[2] = {0, 0}, pcmp[2][KRMQ_MAX_DEPTH], i, cmp, lca; \
+ if (root == 0) return 0; \
+ while (p) { \
+ cmp = __cmp(lo, p); \
+ path[0][plen[0]] = p, pcmp[0][plen[0]++] = cmp; \
+ if (cmp < 0) p = p->__head.p[0]; \
+ else if (cmp > 0) p = p->__head.p[1]; \
+ else break; \
+ } \
+ p = root; \
+ while (p) { \
+ cmp = __cmp(up, p); \
+ path[1][plen[1]] = p, pcmp[1][plen[1]++] = cmp; \
+ if (cmp < 0) p = p->__head.p[0]; \
+ else if (cmp > 0) p = p->__head.p[1]; \
+ else break; \
+ } \
+ for (i = 0; i < plen[0] && i < plen[1]; ++i) \
+ if (path[0][i] == path[1][i] && pcmp[0][i] <= 0 && pcmp[1][i] >= 0) \
+ break; \
+ if (i == plen[0] || i == plen[1]) return 0; /* no elements in the closed interval */ \
+ lca = i, min = path[0][lca]; \
+ for (i = lca + 1; i < plen[0]; ++i) { \
+ if (pcmp[0][i] <= 0) { \
+ if (__lt2(path[0][i], min)) min = path[0][i]; \
+ if (path[0][i]->__head.p[1] && __lt2(path[0][i]->__head.p[1]->__head.s, min)) \
+ min = path[0][i]->__head.p[1]->__head.s; \
+ } \
+ } \
+ for (i = lca + 1; i < plen[1]; ++i) { \
+ if (pcmp[1][i] >= 0) { \
+ if (__lt2(path[1][i], min)) min = path[1][i]; \
+ if (path[1][i]->__head.p[0] && __lt2(path[1][i]->__head.p[0]->__head.s, min)) \
+ min = path[1][i]->__head.p[0]->__head.s; \
+ } \
+ } \
+ return (__type*)min; \
+ }
+
#define __KRMQ_ROTATE(suf, __type, __head, __lt2) \
/* */ \
static inline void krmq_update_min_##suf(__type *p, const __type *q, const __type *r) { \
r->__head.size = p->__head.size - 1; \
} \
} \
- for (i = d - 1; i >= 0; --i) /* not sure why adding condition "path[i]==p" doesn't work */ \
+ for (i = d - 1; i >= 0; --i) /* not sure why adding condition "path[i]->__head.s==p" doesn't work */ \
krmq_update_min_##suf(path[i], path[i]->__head.p[0], path[i]->__head.p[1]); \
while (--d > 0) { \
__type *q = path[d]; \
*/
#define krmq_find(suf, root, x, cnt) krmq_find_##suf(root, x, cnt)
#define krmq_interval(suf, root, x, lower, upper) krmq_interval_##suf(root, x, lower, upper)
+#define krmq_rmq(suf, root, lo, up) krmq_rmq_##suf(root, lo, up)
/**
* Delete a node from the tree
#define KRMQ_INIT2(suf, __scope, __type, __head, __cmp, __lt2) \
__KRMQ_FIND(suf, __scope, __type, __head, __cmp) \
+ __KRMQ_RMQ(suf, __scope, __type, __head, __cmp, __lt2) \
__KRMQ_ROTATE(suf, __type, __head, __lt2) \
__KRMQ_INSERT(suf, __scope, __type, __head, __cmp, __lt2) \
__KRMQ_ERASE(suf, __scope, __type, __head, __cmp, __lt2) \
#include <stdio.h>
+#include <assert.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
} else return 0;
}
+int check_rmq(const struct my_node *root, int lo, int hi)
+{
+ struct my_node s, t, *p, *q;
+ krmq_itr_t(my) itr;
+ int min = INT_MAX;
+ s.key = lo, t.key = hi;
+ p = krmq_rmq(my, root, &s, &t);
+ krmq_interval(my, root, &s, 0, &q);
+ if (p == 0) return -1;
+ krmq_itr_find(my, root, q, &itr);
+ do {
+ const struct my_node *r = krmq_at(&itr);
+ if (r->key > hi) break;
+ //fprintf(stderr, "%c\t%d\n", r->key, r->val);
+ if (r->val < min) min = r->val;
+ } while (krmq_itr_next(my, &itr));
+ assert((min == INT_MAX && p == 0) || (min < INT_MAX && p));
+ if (min != p->val) fprintf(stderr, "rmq_min %d != %d\n", p->val, min);
+ return min;
+}
+
int print_tree(const struct my_node *p)
{
int c = 1;
if (p != q) free(p);
check(root, &h, &min);
}
+
shuffle(n, buf);
for (i = 0; i < n/2; ++i) {
t.key = buf[i];
}
check_and_print(root);
+ check_rmq(root, '0', '9');
+ check_rmq(root, '!', '~');
+ check_rmq(root, 'A', 'Z');
+ check_rmq(root, 'F', 'G');
+ check_rmq(root, 'a', 'z');
+
krmq_itr_first(my, root, &itr);
do {
const struct my_node *r = krmq_at(&itr);