线段树

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5 + 9;
ll n, m, root;
ll a[N];
struct segmentTree {
    struct node {
        ll l, r, L, R, add, sum;
    } tr[N << 3];
    inline void pushup(ll p) {tr[p].sum = (tr[tr[p].l].sum + tr[tr[p].r].sum);}
    inline void pushdown(ll p) {
        if (tr[p].add != 0) {
            ll d = tr[p].add;
            tr[p].add = 0;
            (tr[tr[p].r].sum += d * (tr[tr[p].r].R - tr[tr[p].r].L + 1));
            (tr[tr[p].l].sum += d * (tr[tr[p].l].R - tr[tr[p].l].L + 1));
            (tr[tr[p].l].add += d) ;
            (tr[tr[p].r].add += d) ;
        }
    }
    inline void build(ll l, ll r, ll p) {
        tr[p].l = p << 1;
        tr[p].r = p << 1 | 1;
        tr[p].L = l, tr[p].R = r;
        if (l == r) {
            tr[p].sum = a[l], tr[p].add = 0;
            return;
        }
        ll mid = l + r >> 1;
        build(l, mid, tr[p].l), build(mid + 1, r, tr[p].r);
        pushup(p);
    }
    inline void add(ll l, ll r, ll p, ll k) {
        if (tr[p].L >= l && tr[p].R <= r) {
            tr[p].sum += (tr[p].R - tr[p].L + 1) * k;
            tr[p].add += k;
            return;
        }
        pushdown(p);
        if (tr[tr[p].l].R >= l) add(l, r, tr[p].l, k);
        if (tr[tr[p].r].L <= r) add(l, r, tr[p].r, k);
        pushup(p);
    }
    inline ll ask(ll l, ll r, ll p) {
        ll ret = 0;
        pushdown(p);
        if (tr[p].L >= l && tr[p].R <= r) return tr[p].sum;
        if (tr[tr[p].l].R >= l) (ret += ask(l, r, tr[p].l)) ;
        if (tr[tr[p].r].L <= r) (ret += ask(l, r, tr[p].r)) ;
        return ret;
    }
} T;

signed main() {
    ll n, m;
    ios::sync_with_stdio(0);
    cin >> n >> m;
    for (int i = 1; i <= n; i ++) {
        cin >> a[i];
    }
    T.build(1, n, 1);
    while (m--) {
        ll op;
        cin >> op;
        ll l, r, k;
        if (op == 1) {
            cin >> l >> r >> k;
            T.add(l, r, 1, k);
        } else {
            cin >> l >> r;
            cout << T.ask(l, r,1)<< endl;
            // for (int ii = l; ii <= r; ii ++) {
            //     、、cout << T.ask(ii, ii, 1) << endl;
            // }
            //cout << T.ask(l, r, 1) << endl;
        }
    }
}
posted @ 2021-04-21 13:09  u_yan  阅读(35)  评论(0编辑  收藏  举报