听取WA声一片

P3372 【模板】线段树 1

K_func @ 2024-12-14 17:09:24

#include <bits/stdc++.h>
using namespace std;
template<typename _Tp>
class segment_tree {
protected:
    int n, root, n4, _end;
    vector<_Tp> tree, lazy;
    vector<_Tp> *arr;
    vector<bool> is_lazy;
    void maintain(int l, int r, int p) {
        int mid = l + (r - l) / 2;
        if (l != r && is_lazy[p]) {
            lazy[p * 2] = lazy[p];
            is_lazy[p * 2] = true;
            lazy[p * 2 + 1] = lazy[p];
            is_lazy[p * 2 + 1] = true;
            tree[p * 2] = lazy[p] * (mid - l + 1);
            tree[p * 2 + 1] = lazy[p] * (r - mid);
            lazy[p] = 0;
            is_lazy[p] = 0;
        }
    }
    _Tp range_sum(int l, int r, int cl, int cr, int p) {
        if (l <= cl && r <= cr) return tree[p];
        int mid = cl + (cr - cl) / 2;
        _Tp sum = 0;
        maintain(cl, cr, p);
        if (l <= mid) {
            sum += range_sum(l, r, cl, mid, p * 2);
        }
        if (r > mid) {
            sum += range_sum(l, r, mid + 1, cr, p * 2 + 1);
        }
        return sum;
    }
    void range_set(int l, int r, _Tp val, int cl, int cr, int p) {
        if (l <= cl && r <= cr) {
            lazy[p] = val;
            is_lazy[p] = 1;
            tree[p] = (cr - cl + 1) * val;
        }
        int mid = cl + (cr - cl) / 2;
        maintain(cl, cr, p);
        if (l <= mid) {
            range_set(l, r, val, cl, mid, p * 2);
        }
        if (r > mid) {
            range_set(l, r, val, mid + 1, cr, p * 2 + 1);
        }
        tree[p] = tree[p * 2] + tree[p * 2 + 1];
    }
    void range_add(int l, int r, _Tp val, int cl, int cr, int p) {
        if (l <= cl && cr <= r) {
            lazy[p] += val;
            tree[p] += (cr - cl + 1) * val;
            return;
        }
        int m = cl + (cr - cl) / 2;
        maintain(cl, cr, p);
        if (l <= m) range_add(l, r, val, cl, m, p * 2);
        if (r > m) range_add(l, r, val, m + 1, cr, p * 2 + 1);
        tree[p] = tree[p * 2] + tree[p * 2 + 1];
    }
    void build(int s, int t, int p) {
        if (s == t) {
            tree[p] = (*arr)[s];
            return ;
        }
        int mid = s + (t - s) / 2;
        build(s, mid, p * 2);
        build(mid + 1, t, p * 2 + 1);
        tree[p] = tree[p * 2] + tree[p * 2 + 1];
    }
public:
    explicit segment_tree<_Tp>(vector<_Tp> v) {
        n = v.size();
        n4 = n * 4;
        tree = vector<_Tp>(n4, 0);
        lazy = vector<_Tp>(n4, 0);
        is_lazy = vector<bool>(n4, 0);
        arr = &v;
        _end = n - 1;
        root = 1;
        build(0, _end, 1);
        arr = nullptr;
    }
    _Tp rsum(int l, int r) {
        return range_sum(l, r, 0, _end, root);
    }
    void rset(int l, int r, _Tp val) {
        return range_set(l, r, val, 0, _end, root);
    }
    void radd(int l, int r, _Tp val) {
        return range_add(l, r, val, 0, _end, root);
    }
};

int n, m;
int main() {
    cin >> n >> m;
    vector<long long> arr(n);
    for (int i = 0; i < n; i++) {
        cin >> arr[i];
    }
    segment_tree<long long> st(arr);
    for (int i = 0; i < m; i++) {
        int op;
        cin >> op;
        if (op) {
            int a, b, c;
            cin >> a >> b >> c;
            st.radd(a, b, c);
        } else {
            int a, b;
            cin >> a >> b;
            cout << st.rsum(a, b) << endl;
        }
    }
    return 0;
}

|