关于线段树上二分

学术版

zzy0618 @ 2024-12-11 21:40:59

比如找到区间最左边 <k 的数。

int search(int u, int l, int k) {
        //Find the first element < k in [l, r]
        if(lc[u] == rc[u]) {
            if(minn[u] >= k) return -1;
            return lc[u];
        }
        if(minn[u] >= k) return -1;
        if(rc[u] < l) return -1;
        int res = search(u << 1, l, k);
        if(res != -1) return res;
        return search(u << 1 | 1, l, k);
    }

网上大部分代码都形如这样,没有对其复杂度做出解释,毕竟这玩意会左右两区间都遍历,本人对其复杂度感到质疑。


by mayike @ 2024-12-11 21:46:14

@zzy0618 复杂度就是 O(\log n),因为 if(minn[u] >= k) return -1;,所以如果 l~mid >=k,会直接return -1,不然显然有答案


by Iniaugoty @ 2024-12-11 21:48:50

大大的 gty 瞪着小小的眼睛:没见过这种写法


by jason_sun @ 2024-12-12 09:10:37

return法其实蛮有道理的,不过常数稍大。我一开始写的在每个if判定该往哪边走非常大码量


|