30分求调

P3372 【模板】线段树 1

wyh725 @ 2023-12-08 21:02:32

求助,跟着刘汝佳训练指南写的,只能过三个点,希望dalao帮忙调一下谢谢!orz

#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int maxn = 4 * 200010;
ll n, m, a[maxn], sum[maxn], addv[maxn];
ll l, r;

void build(int o, int l, int r){
    if(l == r){
        sum[o] = a[l];
        return;
    }
    int lc = 2*o, rc =2*o + 1;
    int m = l + (r-l)/2;
    build(lc, l, m);
    build(rc, m+1, r);
    sum[o] = sum[lc] + sum[rc];
}

void maintain(int o, int l, int r){
    int lc = 2*o, rc =2*o + 1;

    if(r > l){
        sum[o] = sum[lc] + sum[rc];
    }
    sum[o] += addv[o] * (r-l+1);
}
ll ql, qr, v;

void update(int o, int l, int r){
    int lc = 2*o, rc =2*o + 1;
    int m = l + (r-l)/2;
    if(ql <= l && qr >= r){
        addv[o] += v;
    }
    else{
        if(ql <= m) {
            update(lc, l, m);
        }
        if(qr > m){
            update(rc, m+1, r);
        }
    }

    maintain(o, l, r);
}

ll sumv;
void query(int o, int l, int r, ll add){
    int m = l + (r-l)/2;
    int lc = 2*o, rc =2*o + 1;
    if(ql <= l && qr >= r){
        sumv += sum[o] + add * (r-l+1); 
    }
    else{
        if(ql <= m) query(lc, l, m, addv[o] + add);
        if(qr > m) query(rc, m+1, r, addv[o] + add);
    }
} 

int main(){
    cin >> n >> m;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
    }
    build(1, 1, n);
    while(m--){
        sumv = 0;
        int f;
        cin >> f >> ql >> qr;
        if(f == 1){
            cin >> v;
            update(1, 1, n);
        }
        if(f == 2){
            query(1, 1, n, 0);
            cout << sumv << endl;
        }
    }
    return 0;
}  

|