線段樹模板2.0
阿新 • • 發佈:2020-10-05
線段樹 區間修改
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(""); } } }