RE 求调

P3372 【模板】线段树 1

__int127 @ 2024-06-10 22:20:43

#include <bits/stdc++.h>
using namespace std;
//#define int long long
#define ll long long
#define endl cout << "\n"
const int N = 1e6 + 5;
int T = 1, n, m, a[N];
struct node{
    int L, R, w, tag;
}tree[N * 4];
void pushup(int u){
    tree[u].w = tree[u * 2].w + tree[u * 2 + 1].w;
}
void build(int u, int L, int R){
    if (L == R){
        tree[u].w = a[L];
        return;
    }
    int m = (L + R) / 2;
    build(u * 2, L, m);
    build(u * 2 + 1, m + 1, R);
    pushup(u);
}
void maketag(int u, int len, ll x){
    tree[u].tag += x;
    tree[u].w += x * len;
}
void pushdown(int u, int L, int R){
    int m = (L + R) / 2;
    maketag(u * 2, m - L + 1, tree[u].tag);
    maketag(u * 2 + 1, R - m, tree[u].tag);
    tree[u].tag = 0;
}
bool in(int l, int r, int L, int R){
    return (l <= L) && (R <= r);
}
bool out(int l, int r, int L, int R){
    return (L > r) || (R < l);
}
int query(int u, int L, int R, int l, int r){
    if (in(l, r, L, R)){
        return tree[u].w;
    } else if (!out(l, r, L, R)){
        int m = (L + R) / 2;
        pushdown(u, L, R);
        return query(u * 2, L, m, l, r) + query(u * 2 + 1, m + 1, R, l, r);
    }
}
void update(int u, int L, int R, int l, int r, ll x){
    if (in(l, r, L, R)){
        maketag(u, R - L + 1, x);
    } else if (!out(l, r, L, R)){
        int m = (L + R) / 2;
        pushdown(u, L, R);
        update(u * 2, L, m, l, r, x);
        update(u * 2 + 1, m + 1, R, l, r, x);
        pushup(u);
    }
}
signed main(){
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    //cin >> T;
    while (T--){
        cin >> n >> m;
        for (int i = 1; i <= n; i++){
            cin >> a[i];
        }
        build(1, 1, n);
        int op, l, r, k;
        while (m--){
            cin >> op >> l >> r;
            if (op == 1){
                cin >> k;
                update(1, 1, n, l, r, k);
            } else {
                cout << query(1, 1, n, l, r);
                endl;
            }
        }
    }
    return 0;
}

by __int127 @ 2024-06-10 22:22:07

本地测没问题


by Terrible @ 2024-06-10 22:43:36

你这个 query 没有覆盖所有情况,存在一种情况使得访问到 query 函数结尾(这种情况是不合乎程序规范的),由于 query 不是 void 函数,编译出来的程序会出各种问题。

对于非 void 函数,要么你要确保它必然在 if 分支当中 return,否则应该在函数末尾加一个警告装置,或者 return 一个特殊值。


by Terrible @ 2024-06-10 22:50:59

在函数 queryupdate 中(特别是 query 中):

in(...)(l<=L)&&(R<=r);

!out(...)!((L>r)||(R<l))(L<=r)&&(R>=l)

没有讨论 R<lL>rl<L&&L<=r&&r<=RL<=l&&l<=R&&R<r 这种情况。


by Terrible @ 2024-06-10 22:53:04

缺失的 4 种情况在 query 中很可能会让程序暴毙,在 update 中直接结束函数了。


by 杜都督 @ 2024-06-10 22:55:38

@Moss_Spresd

  1. query()最后return 0;

  2. w、tag、query开long long


|