权值线段树找前驱后继
问题是我们要在$[L,R]$的区间内找第一个在$pos$前面/后面出现的值。
这个可以转化为在权值线段树上找前驱后继。
前驱问题的具体解决方法是。
如果$pos$在当前区间的左半边那么答案一定在左区间,于是递归到左区间寻找。
否则优先在右区间进行寻找,如果找到答案的话就返回,否则再在左区间寻找。
int getpre(int l, int r, int o1, int o2, int pos) { if (!(tr[o2] - tr[o1])) return 0; if (l == r) return l; int mid = (l + r) >> 1; if (pos <= mid) return getpre(l, mid, ls[o1], ls[o2], pos); int t = getpre(mid + 1, r, rs[o1], rs[o2], pos); if (t) return t; return getpre(l, mid, ls[o1], ls[o2], pos); }
查询后继类似。
int getnxt(int l, int r, int o1, int o2, int pos) { if (!(tr[o2] - tr[o1])) return 0; if (l == r) return l; int mid = (l + r) >> 1; if (pos > mid) return getnxt(mid + 1, r, rs[o1], rs[o2], pos); int t = getnxt(l, mid, ls[o1], ls[o2], pos); if (t) return t; return getnxt(mid + 1, r, rs[o1], rs[o2], pos); }