1. 程式人生 > 實用技巧 >線段樹模板2.0

線段樹模板2.0

線段樹 區間修改

struct Tree {
    int l, r;
    ll val;
};

Tree node[maxn << 2];
ll lazy[maxn << 2];
ll a[maxn];


void push_up(int i) {
    node[i].val = node[i << 1].val + node[i << 1 | 1].val;
}

void build(int i, int l, int r) {
    node[i].l = l;
    node[i].r = r;
    if (l == r) {
        node[i].val = a[l];
        return;
    }
    int mid = l + r >> 1;
    build(i << 1, l, mid);
    build(i << 1 | 1, mid + 1, r);
    push_up(i);
}

void push_down(int i,int m) {
    if (lazy[i]) {
        lazy[i << 1] += lazy[i];
        lazy[i << 1 | 1] += lazy[i];
        node[i << 1].val += lazy[i] * (m - (m >> 1));
        node[i << 1 | 1].val += lazy[i] * (m >> 1);
        lazy[i] = 0;
    }
}

void update(int i, int l, int r,ll val) {
    if (node[i].l > r || node[i].r < l) return;
    if (node[i].l >= l && node[i].r <= r) {
        lazy[i] += val;
        node[i].val += (node[i].r - node[i].l + 1) * val;
        return;
    }
    push_down(i, node[i].r - node[i].l + 1);
    update(i << 1, l, r, val);
    update(i << 1 | 1, l, r, val);
    push_up(i);
}

ll get_sum(int i, int l, int r) {
    if (node[i].l > r || node[i].r < l) return 0;
    if (node[i].l >= l && node[i].r <= r) return node[i].val;
    push_down(i, node[i].r - node[i].l + 1);
    return get_sum(i << 1, l, r) + get_sum(i << 1 | 1, l, r);
}

int main() {
    int n = readint();
    int m = readint();
    for (int i = 1; i <= n; i++)
        a[i] = readll();
    build(1, 1, n);
    while (m--) {
        int q = readint();
        int x = readint();
        int y = readint();
        if (q == 1) {
            ll val = readll();
            update(1,x, y, val);
        }
        else {
            Put(get_sum(1, x, y));
            puts("");
        }
    }
}