线段树板子题求助
查看原帖
线段树板子题求助
574944
Micnation_AFO楼主2021/11/26 21:06

rt,样例都过不去,最后一项操作输出“16”,正确答案是“18”。

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

#define int long long 
#define maxn 1000005
struct SegmentTree {
    int l, r;
    int sum, add;
} t[maxn * 4];
int n, m;
int a[maxn];

void build(int p, int l, int r) {
    t[p].l = l, t[p].r = r;
    if (l == r) {t[p].sum = a[l]; return; }
    int mid = (l + r) >> 1;
    build(p * 2, l, mid), build(p * 2 + 1, mid + 1, r);
    t[p].sum = t[p * 2].sum + t[p * 2 + 1].sum;
}

void spread(int p) {
    if (t[p].add) {
        t[p].sum += t[p].add * (t[p * 2].r - t[p * 2].l + 1);
        t[p].sum += t[p].add * (t[p * 2 + 1].r - t[p * 2 + 1].l + 1);
        t[p * 2].add += t[p].add, t[p * 2 + 1].add = t[p].add;
        t[p].add = 0;
    }
}

int ask(int p, int l, int r) {
    if (l <= t[p].l && r >= t[p].r) return t[p].sum;
    spread(p);
    int mid = (t[p].l + t[p].r) >> 1;
    int ans = 0;
    if (l <= mid) ans += ask(p * 2, l, r);
    if (r > mid) ans += ask(p * 2 + 1, l, r);
    return ans;
}

void change(int p, int x, int y, int k) {
    if (x <= t[p].l && y >= t[p].r) {
        t[p].sum += k * (t[p].r - t[p].l + 1);
        t[p].add += k;
        return;
    }
    spread(p);
    int mid = (t[p].l + t[p].r) >> 1;
    if (x <= mid) change(p * 2, x, y, k);
    if (y > mid) change(p * 2 + 1, x, y, k);
    t[p].sum = t[p * 2].sum + t[p * 2 + 1].sum;
}

signed main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) cin >> a[i];
    build(1, 1, n);
    for (int i = 1; i <= m; i++) {
        int op, x, y, k; cin >> op;
        if (op == 1) {
            cin >> x >> y >> k;
            change(1, x, y, k);
        }
        else {
            cin >> x >> y;
            cout << ask(1, x, y) << endl;
        }
    }
    return 0;
}

2021/11/26 21:06
加载中...