板子求调

P3372 【模板】线段树 1

ragwort @ 2023-02-15 23:01:32

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5+10;

int t[N*4],a[N],n,m;

inline void build(int k,int l,int r){
    if(l == r){
        t[k] = a[l];
        return ;
    }

    int mid = l + r >> 1;
    build(k*2,l,mid);
    build(k*2+1,mid+1,r);

    t[k] = t[k*2]+t[k*2+1];
}

inline void update(int k,int l,int r,int v){
    if(l == r){
        t[k] += v;
        return ;
    }

    int mid = l + r >> 1;
    update(k*2,l,mid,v);
    update(k*2+1,mid+1,r,v);

    t[k] = t[k*2] + t[k*2+1];
}

inline int query(int k,int l,int r,int x,int y){
    if(x <= l && y >= r) return t[k];

    int mid = l+r>>1,res=0;
    if(x <= mid) res = query(k*2,l,mid,x,y);
    if(y > mid) res += query(k*2+1,mid+1,r,x,y);

    return res;
}

signed main() {

    cin >> n >> m;

    for(int i = 1; i <= n; i++)
        cin >> a[i];

    int x,y,z;
    while(m--){
        cin >> x;
        if(x == 2){
            cin >> x >> y;
            cout << query(1,1,n,x,y) << endl;
        }else{
            cin >> x >> y >> z;
            update(1,x,y,z);
        }
    }

    return 0;
}

谢谢


by TheSky233 @ 2023-02-15 23:04:16

所以您的 build 呢


by ragwort @ 2023-02-15 23:06:00

@TheSky233 加上了,但是WA(


by scp020 @ 2023-02-15 23:09:08

没有懒惰标记的线段树


by scp020 @ 2023-02-15 23:09:29

建议学习题解。


by qwq___qaq @ 2023-02-15 23:12:44

@wind_kaka 你 update 的时候会加入一些本来不属于查询区间的区间


by ragwort @ 2023-02-15 23:14:31

@UnnamedOrNamed 那我在判断是否叶子节点的时候判断一下就行了吗?


by qwq___qaq @ 2023-02-15 23:15:04

@wind_kaka 但是你部分节点的子节点没加到,所以用个懒惰标记


by ragwort @ 2023-02-15 23:16:22

@UnnamedOrNamed 我润去学懒惰标记力


by creation_hy @ 2023-02-16 02:44:05

你认真的吗……


by Placy @ 2023-02-16 06:32:12

@wind_kaka update 时如果 l == r 那么应该加上 (r - l + 1) * v,另外,不仅是这个节点被加了,子树也要加,打懒标记 add[k] += v;

每一次 update 或者 query 都要下传标记。

或者写标记永久化


| 下一页