線段樹(單點/區間)模板

單點

struct Tree {
    struct {
        int l, r;
        ll dat;
    } t[M * 4];

    void build(int p, int l, int r) {
        t[p].l = l, t[p].r = r;
        if (l == r) {
            t[p].dat = -1e12;
            return;
        }
        int mid = (l + r) >> 1;
        build(p << 1, l, mid);
        build(p << 1 | 1, mid + 1, r);
        t[p].dat = -1e12;
    }

    void change(int p, int x, ll v) {
        if (t[p].l == t[p].r) {
            t[p].dat = v;
            return;
        }
        int mid = (t[p].l + t[p].r) >> 1;
        if (x <= mid)change(p << 1, x, v);
        else change(p << 1 | 1, x, v);
        t[p].dat = max(t[p << 1].dat, t[p << 1 | 1].dat);
    }

    ll ask(int p, int l, int r) {
        if (l <= t[p].l && r >= t[p].r)return t[p].dat;
        int mid = (t[p].l + t[p].r) >> 1;
        ll val = -1e12;
        if (l <= mid)val = max(val, ask(p << 1, l, r));
        if (r > mid)val = max(val, ask(p << 1 | 1, l, r));
        return val;
    }
};

區間

struct Tree {
    struct T {
        int l, r, ans, add;
#define l(x) t[x].l
#define r(x) t[x].r
#define ans(x) t[x].ans
#define add(x) t[x].add
    } t[N * 8];
    void build(int p, int l, int r) {
        l(p) = l, r(p) = r, ans(p) = add(p) = 0;
        if (l == r)return;
        int mid = (l + r) >> 1;
        build(p << 1, l, mid);
        build(p << 1 | 1, mid + 1, r);
    }
    void spread(int p) {
        if (add(p)) {
            ans(p << 1) += add(p);
            ans(p << 1 | 1) += add(p);
            add(p << 1) += add(p);
            add(p << 1 | 1) += add(p);
            add(p) = 0;
        }
    }
    void change(int p, int l, int r, int c) {
        if (l <= l(p) && r(p) <= r) {
            add(p) += c;
            ans(p) += c;
            return;
        }
        spread(p);
        int mid = (l(p) + r(p)) >> 1;
        if (l <= mid)change(p << 1, l, r, c);
        if (r > mid)change(p << 1 | 1, l, r, c);
        ans(p) = max(ans(p << 1), ans(p << 1 | 1));
    }
    int ask(int p,int l,int r){
        if(l<=l(p)&&r>=r(p))return ans(p);
        spread(p);
        int mid=(l(p)+r(p))>>1;
        int val=0;
        if(l<=mid)val+=ask(p<<1,l,r);
        if(r>mid)val+=ask(p<<1|1,l,r);
        return val;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章