求各种线段树的写法
  • 板块灌水区
  • 楼主Micnation_AFO
  • 当前回复6
  • 已保存回复6
  • 发布时间2022/1/21 11:20
  • 上次更新2023/10/28 11:41:54
查看原帖
求各种线段树的写法
574944
Micnation_AFO楼主2022/1/21 11:20

rt,目前本人的写法:

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

#define int long long 
#define maxn 1000005
struct SegmentTree {
    int l, r;
    int sum = 0, add = 0;
} 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 * 2].sum += t[p].add * (t[p * 2].r - t[p * 2].l + 1);
        t[p * 2 + 1].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;
}
2022/1/21 11:20
加载中...