样例过了,但是0分代码求助

P3372 【模板】线段树 1

wahe @ 2025-01-08 17:12:27

自己测试了很久,找不出问题
代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
int w[1000005], a[1000005], lzy[1000005];
int n, m;

bool irange(int nl, int nr, int l, int r) {
    return (nl >= l && nr <= r);
}

bool orange(int nl, int nr, int l, int r) {
    return (nl > r) || (nr < l);
}

void push_up(int u) {
    w[u] = w[u * 2] + w[u * 2 + 1];
} 

void make_tag(int u, int len, int k){
    lzy[u] += k;
    w[u] += k * len;    
}

void push_down(int u, int nl, int nr) {
    int m = (nl + nr) / 2;
    make_tag(u * 2, (m - nl + 1), lzy[u]);
    make_tag(u * 2 + 1, (nr - m), lzy[u]);  
    lzy[u] = 0;
}

void build(int u, int l, int r) {
    if(l == r) {
        w[u] = a[l];
        return;
    }
    int mid = (l + r) / 2;
    build(u * 2, l, mid);
    build(u * 2 + 1, mid + 1, r);
    push_up(u);
}

int sum(int u, int nl, int nr, int l, int r){
    if(irange(nl, nr, l, r)) {
        return w[u];
    }
    else if(!orange(nl, nr, l, r)) {
        push_down(u, nl, nr);
        int mid = (nl + nr) / 2;
        return sum(u * 2, nl, mid, l, r) + sum(u * 2 + 1, mid + 1, nr, l, r);
    }
    else return 0;
}

void plu(int u, int nl, int nr, int l, int r, int k) {
    if(irange(nl, nr, l, r)) {
        make_tag(u, (nr - nr + 1), k);  
        return ;
    }

    if(!orange(nl, nr, l, r)) {
        int mid = (nl + nr) / 2;
        push_down(u, nl, nr);
        plu(u * 2, nl, mid, l, r, k);
        plu(u * 2 + 1, mid + 1, nr, l, r, k);
        push_up(u); 
    }
}

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;
        int x, y, k;
        cin >> op >> x >> y;
        if(op == 1) {
            cin >> k;
            plu(1, 1, n, x, y, k);  
        }
        else {
            cout << sum(1, 1, n, x, y) << endl;
        }
    }
    return 0;
} 

by JoyLosingK @ 2025-01-08 18:16:28

@wahe

plu 函数中的 make_tag 参数错了,具体看代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
int w[1000005], a[1000005], lzy[1000005];
int n, m;

bool irange(int nl, int nr, int l, int r) {
    return (nl >= l && nr <= r);
}

bool orange(int nl, int nr, int l, int r) {
    return (nl > r) || (nr < l);
}

void push_up(int u) {
    w[u] = w[u * 2] + w[u * 2 + 1];
} 

void make_tag(int u, int len, int k){
    lzy[u] += k;
    w[u] += k * len;    
}

void push_down(int u, int nl, int nr) {
    int m = (nl + nr) / 2;
    make_tag(u * 2, (m - nl + 1), lzy[u]);
    make_tag(u * 2 + 1, (nr - m), lzy[u]);  
    lzy[u] = 0;
}

void build(int u, int l, int r) {
    if(l == r) {
        w[u] = a[l];
        return;
    }
    int mid = (l + r) / 2;
    build(u * 2, l, mid);
    build(u * 2 + 1, mid + 1, r);
    push_up(u);
}

int sum(int u, int nl, int nr, int l, int r){
    if(irange(nl, nr, l, r)) {
        return w[u];
    }
    else if(!orange(nl, nr, l, r)) {
        push_down(u, nl, nr);
        int mid = (nl + nr) / 2;
        return sum(u * 2, nl, mid, l, r) + sum(u * 2 + 1, mid + 1, nr, l, r);
    }
    else return 0;
}

void plu(int u, int nl, int nr, int l, int r, int k) {
    if(irange(nl, nr, l, r)) {
        make_tag(u, (nr - nl + 1), k);  
        return ;
    }

    if(!orange(nl, nr, l, r)) {
        int mid = (nl + nr) / 2;
        push_down(u, nl, nr);
        plu(u * 2, nl, mid, l, r, k);
        plu(u * 2 + 1, mid + 1, nr, l, r, k);
        push_up(u); 
    }
}

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;
        int x, y, k;
        cin >> op >> x >> y;
        if(op == 1) {
            cin >> k;
            plu(1, 1, n, x, y, k);  
        }
        else {
            cout << sum(1, 1, n, x, y) << endl;
        }
    }
    return 0;
}

by wahe @ 2025-01-08 18:26:22

@JoyLosingK 已解决,谢谢


|