← 返回题目页

A2446 守墓人(无数据)

标程

#include <bits/stdc++.h>
using namespace std;

struct SegTree {
    int n;
    vector<long long> sum, lazy;
    explicit SegTree(const vector<long long> &a)
        : n((int)a.size()), sum(4 * n + 4, 0), lazy(4 * n + 4, 0) {
        if (n > 0) build(1, 0, n - 1, a);
    }
    void build(int p, int l, int r, const vector<long long> &a) {
        if (l == r) { sum[p] = a[l]; return; }
        int m = (l + r) / 2;
        build(p * 2, l, m, a);
        build(p * 2 + 1, m + 1, r, a);
        sum[p] = sum[p * 2] + sum[p * 2 + 1];
    }
    void apply(int p, int l, int r, long long v) {
        sum[p] += v * (r - l + 1);
        lazy[p] += v;
    }
    void push(int p, int l, int r) {
        if (lazy[p] == 0 || l == r) return;
        int m = (l + r) / 2;
        apply(p * 2, l, m, lazy[p]);
        apply(p * 2 + 1, m + 1, r, lazy[p]);
        lazy[p] = 0;
    }
    void add(int p, int l, int r, int ql, int qr, long long v) {
        if (ql <= l && r <= qr) { apply(p, l, r, v); return; }
        push(p, l, r);
        int m = (l + r) / 2;
        if (ql <= m) add(p * 2, l, m, ql, qr, v);
        if (qr > m) add(p * 2 + 1, m + 1, r, ql, qr, v);
        sum[p] = sum[p * 2] + sum[p * 2 + 1];
    }
    long long query(int p, int l, int r, int ql, int qr) {
        if (ql <= l && r <= qr) return sum[p];
        push(p, l, r);
        int m = (l + r) / 2;
        long long res = 0;
        if (ql <= m) res += query(p * 2, l, m, ql, qr);
        if (qr > m) res += query(p * 2 + 1, m + 1, r, ql, qr);
        return res;
    }
    void add(int l, int r, long long v) { if (n > 0 && l <= r) add(1, 0, n - 1, l, r, v); }
    long long query(int l, int r) { return (n > 0 && l <= r) ? query(1, 0, n - 1, l, r) : 0; }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, f;
    cin >> n >> f;
    vector<long long> a(n);
    for (int i = 0; i < n; i++) cin >> a[i];

    // 1 号是主墓碑,单独维护;2..n 号次要墓碑放进线段树
    long long mainVal = a[0];
    SegTree seg(vector<long long>(a.begin() + 1, a.end()));

    for (int i = 0; i < f; i++) {
        int op;
        cin >> op;
        if (op == 1) {
            int l, r;
            long long k;
            cin >> l >> r >> k;
            if (l == 1) { mainVal += k; l = 2; }   // 区间覆盖 1 号时主墓碑单独加
            seg.add(l - 2, r - 2, k);
        } else if (op == 2) {
            long long k;
            cin >> k;
            mainVal += k;
        } else if (op == 3) {
            long long k;
            cin >> k;
            mainVal -= k;
        } else if (op == 4) {
            int l, r;
            cin >> l >> r;
            long long ans = (l == 1 ? mainVal : 0);
            ans += seg.query(max(l, 2) - 2, r - 2);
            cout << ans << '\n';
        } else {
            cout << mainVal << '\n';
        }
    }
    return 0;
}

动画演示