线段树样例能过 10pts 求调,玄关。

P3372 【模板】线段树 1

_Gabriel_ @ 2023-09-03 11:36:23

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

typedef long long ll;
#define long long int
const int INF = 9e18;
const int N = 1e5 + 10;
int minv[N * 4], maxv[N * 4], sumv[N * 4], a[N], lazy[4 * N];
int n, m;

void pushup(int id) {
    minv[id] = min(minv[id << 1], minv[id << 1 | 1]);
    maxv[id] = max(maxv[id << 1], maxv[id << 1 | 1]);
    sumv[id] = sumv[id << 1] + sumv[id << 1 | 1];
}

void pushdown(int id, int l, int r) {
    if (lazy[id]) {
        int mid = (l + r) >> 1;
        //标记的下标
        lazy[id << 1] += lazy[id];
        lazy[id << 1 | 1] += lazy[id];
        //左区间更新
        minv[id << 1] += lazy[id];
        maxv[id << 1] += lazy[id];
        sumv[id << 1] += (mid - l + 1) * lazy[id];
        //右区间更新
        minv[id << 1 | 1] += lazy[id];
        maxv[id << 1 | 1] += lazy[id];
        sumv[id << 1 | 1] += (r - mid) * lazy[id];              
    }
}

//id 表示节点编号,l r 表示这个节点对应的区间 
void build(int id, int l, int r) {
    if (l == r) {
        //如果当前区间是长度为 1 的叶子节点 
        minv[id] = maxv[id] = sumv[id] = a[l];
        return;
    }
    //否则的话从中间拆分开左右两个区间 
    int mid = (l + r) >> 1;//(l + r) >> 1 ==> (l + r) / 2 
    build(id << 1, l, mid);//id << 1 ==> id * 2 
    build(id << 1 | 1, mid + 1, r);//id << 1 | 1 ==> id * 2 + 1 
    //左右两个孩子的结果全部计算完毕后
    //把结果合并到当前节点 
    pushup(id);
} 

void interval_update(int id, int l, int r, int x, int y, int v) {//区间更新
    if (x <= l && r <= y) {
        lazy[id] += v;
        minv[id] += v;
        maxv[id] += v;
        sumv[id] += (r - l + 1) * v;
        return;
    }
    pushdown(id, l, r);
    int mid = (l + r) >> 1;
    if (x <= mid) {
        interval_update(id << 1, l, mid, x, y, v);
    } 
    if (y > mid) {
        interval_update(id << 1 | 1, mid + 1, r, x, y, v);
    }
    pushup(id);
}

int query(int id, int l, int r, int x, int y) {
    if (x <= l && r <= y) {
        return sumv[id];
    }
    pushdown(id, l, r);
    int mid = (l + r) >> 1;
    int ans = 0;
    if (x <= mid) {
        ans += query(id << 1, l, mid, x, y);
    }  
    if (y > mid) {
        ans += query(id << 1 | 1, mid + 1, r, x, y);
    }
    return ans;
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
    }
    build(1, 1, n);
    int op, x, y, k;
    for (int i = 1; i <= m; i++) {
        scanf("%d", &op);
        if (op == 1) {
            scanf("%d%d%d", &x, &y, &k);
            interval_update(1, 1, n, x, y, k);
        } else {
            scanf("%d%d", &x, &y);
            printf("%d\n", query(1, 1, n, x, y));
        }
    }
    return 0;
}

by ForgotDream_CHN @ 2023-09-03 11:54:05

#define long long int 是什么玩意啊


by _Gabriel_ @ 2023-09-03 11:58:55

@ForgotDream_CHN 还有其他问题吗


by Stevehim @ 2023-09-03 12:03:39

@tanzk lazy[id]没清空,加上前面的#define int long long 能得70


by Stevehim @ 2023-09-03 12:05:31

@tanzk 然后输出部分改为%lld


by Stevehim @ 2023-09-03 12:05:44

就过了


by _Gabriel_ @ 2023-09-03 12:13:54

@Stevehim @ForgotDream_CHN 谢谢大佬的认真回复,已关.


|