線段樹分裂 學習筆記

Z_drj發表於2024-05-26

過程

線段樹分裂是線段樹合併的逆操作,即將一個區間資訊分裂到新的樹中,新的樹一般需要新建。

注意當分裂和合並都存在時,我們在合併的時候必須回收節點,以避免分裂時會可能出現節點重複佔用的問題。

時間複雜度顯然 \(\mathcal{O}(\log n)\)

實現

//將 x 分裂出 [p, q] 到 now 上
void split(int &x, int &now, int l, int r, int p, int q){
        if (!x) {
            return;
        }
        
        if (p <= l && r <= q) {
            now = x;
            x = 0;
            return;
        }
        
        if (!now) {
            New(now);
        }

        int mid = l + r >> 1;
        if (p <= mid) {
            split(s[x].l, s[now].l, l, mid, p, q);
        }

        if (q > mid) {
            split(s[x].r, s[now].r, mid + 1, r, p, q);
        }

        pushup(x), pushup(now);
    }

相關文章