动态开点线段树

动态开点线段树原理

例题 1

统计区间中的整数数目

#define ls(x) tr[x].L
#define rs(x) tr[x].R
class CountIntervals {
    static const int N = 8e5 + 5;
    struct node{
        int l, r, cnt = 0;
        int L = -1, R = -1;
    }tr[N];
    int idx = 1;
    void push_up(int u) {
        tr[u].cnt = 0;
        if (ls(u) != -1) {
            tr[u].cnt += tr[ls(u)].cnt;
        }
        if (rs(u) != -1) {
            tr[u].cnt += tr[rs(u)].cnt;
        }
    }
    void add2(int u, int l, int r) {
        if (tr[u].l == tr[u].r) {
            tr[u].cnt = 1;
            return;
        }
        if (l <= tr[u].l && r >= tr[u].r) {
            tr[u].cnt = tr[u].r - tr[u].l + 1;
            return;
        }
        if (tr[u].cnt == tr[u].r - tr[u].l + 1) return;
        int mid = (tr[u].l + tr[u].r) >> 1;

        if (l <= mid) {
            int& L = ls(u);
            if (L == -1) {
                L = idx ++;
                tr[L] = {tr[u].l, mid};
            }
            add2(L, l, r);
        }
        if (r > mid) {
            int& R = rs(u);
            if (R == -1) {
                R = idx ++;
                tr[R] = {mid + 1, tr[u].r};
            }
            add2(R, l, r);
        }
        push_up(u);
    }

public:
    CountIntervals() {
        tr[idx ++] = {1, 1000000005, 0};
    }

    void add(int left, int right) {
        add2(1, left, right);
        // cout << idx << endl;
    }

    int count() {
        // cout << idx << endl;
        return tr[1].cnt;
    }
};

/**
 * Your CountIntervals object will be instantiated and called as such:
 * CountIntervals* obj = new CountIntervals();
 * obj->add(left,right);
 * int param_2 = obj->count();
 */

例题 2

Range 模块

#define ls(u) tr[u].L
#define rs(u) tr[u].R
class RangeModule {
    static const int N = 1E6;
    struct node{
        int l, r;
        int L, R;
        int sum = 0;
        int f = 0;
    }tr[4 * N];
    int idx = 1;
    void push_up(int u) {
        tr[u].sum = tr[ls(u)].sum + tr[rs(u)].sum;
    }
    void push_dowm(int u) {
        int& L = ls(u), &R = rs(u);
        if (!L) {
            L = ++ idx;
            tr[L] = {tr[u].l, tr[u].l + tr[u].r >> 1};
        }
        if (!R) {
            R = ++ idx;
            tr[R] = {(tr[u].l + tr[u].r >> 1) + 1, tr[u].r};
        }

        if (tr[u].f == 0) return;
        else if (tr[u].f == -1) {
            tr[L].sum = 0;
            tr[R].sum = 0;
        }else {
            int len = tr[u].r - tr[u].l + 1;
            tr[L].sum = len - len / 2;
            tr[R].sum = len / 2;
        }
        tr[L].f = tr[u].f;
        tr[R].f = tr[u].f;
        tr[u].f = 0;
    }
    void update(int u, int l, int r, int f) {
        if (l <= tr[u].l && tr[u].r <= r) {
            tr[u].f = f;
            if (f == 1)
                tr[u].sum = tr[u].r - tr[u].l + 1;
            else tr[u].sum = 0;
            return;
        }
        int mid = tr[u].r + tr[u].l >> 1;
        push_dowm(u);
        if (l <= mid) update(ls(u), l, r, f);
        if (r > mid) update(rs(u), l, r, f);
        push_up(u);
    }
    int query(int u, int l, int r) {
        if (l <= tr[u].l && tr[u].r <= r) {
            return tr[u].sum;
        }
        int mid = tr[u].l + tr[u].r >> 1;
        push_dowm(u);
        int ret = 0;
        if (l <= mid) ret += query(ls(u), l, r);
        if (r > mid) ret += query(rs(u), l, r);
        return ret;
    }
public:
    RangeModule() {
        tr[1] = {1, 1000000005};
    }

    void addRange(int left, int right) {
        update(1, left, right - 1, 1);
    }

    bool queryRange(int left, int right) {
        // if (left == 13 && right == 15) cout << query(1, 13, 14) << endl;
        return query(1, left, right - 1) == (right - left);
    }

    void removeRange(int left, int right) {
        update(1, left, right - 1, -1);
    }
};

/**
 * Your RangeModule object will be instantiated and called as such:
 * RangeModule* obj = new RangeModule();
 * obj->addRange(left,right);
 * bool param_2 = obj->queryRange(left,right);
 * obj->removeRange(left,right);
 */
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇