求助,用了懒标记,但还是超时了

P3372 【模板】线段树 1

huyangmu @ 2023-12-11 22:55:01



#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int NR = 1e5 + 5;
int n,m,id,x,y,k,a[NR],tree[4 * NR],tag[4 * NR];
void pushup (int x){
    tree[x] = tree[(x << 1)] + tree[(x << 1) + 1];
    return ;
}
void addtag (int l,int r,int x,int val){
    tag[x] += val;
    tree[x] += (r - l + 1) * val;
    return ;
}
void pushdown (int l,int r,int x){
    if (tag[x] == 0) return ;
    int mid = l + r >> 1;
    addtag(l,mid,(x << 1),tag[(x << 1)]);
    addtag(mid + 1,r,(x << 1) + 1,tag[(x << 1) + 1]);
    tag[x] = 0;
    return ;
}
void build (int l,int r,int x){
    if (l == r){
        tree[x] = a[l];
        return ;
    }
    int mid = l + r >> 1;
    build(l,mid,(x << 1));
    build(mid + 1,r,(x << 1) + 1);
    pushup(x);
    return ;
}
int query (int l,int r,int x,int y,int cur){
    if (y < l || x > r) return 0;
    if (x <= l && r <= y) return tree[cur];
    pushdown(l,r,cur);
    int mid = l + r >> 1;
    return query(l,mid,x,y,(cur << 1)) + query(mid + 1,r,x,y,(cur << 1) + 1);
}
void update (int l,int r,int x,int y,int cur,int val){
    if (y < l || x > r) return ;
    if (l == r && x <= l && r <= y){
        addtag(l,r,cur,val);        
        return ;
    }
    pushdown(l,r,cur);
    int mid = l + r >> 1;
    update(l,mid,x,y,(cur << 1),val);
    update(mid + 1,r,x,y,(cur << 1) + 1,val);
    pushup(cur);
    return ;
}
signed main (){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin >> n >> m;
    for (int i = 1;i <= n; ++i) cin >> a[i];
    build (1,n,1);
    while (m--){
        cin >> id;
        if (id == 1){
            cin >> x >> y >> k; 
            update(1,n,x,y,1,k);
        }else{
            cin >> x >> y;
            cout << query (1,n,x,y,1) << '\n'; 
        }
    }
    return 0;
}

by HYdroKomide @ 2023-12-11 22:57:33

@HuYangMu2011 pushdown 那里 add 的 tag 写错了。


by huyangmu @ 2023-12-11 22:58:44

具体是哪@HYdroKomide


by HYdroKomide @ 2023-12-11 23:00:01

@HuYangMu2011 pushdown 那里的 addtag 函数里,应该都传 tag[x],你看看你传的是什么


by huyangmu @ 2023-12-11 23:02:47

%%% 关注了@HYdroKomide


by hsdqiu @ 2023-12-16 19:38:31

我猜是query的递归返回条件不对 你这个和我的写法不一样,但是我的是多加了第一个else if,然后就不超时了。 原本的是每次都到根节点才返回

int query(int k, int l, int r)      //当前到了编号为k的节点,查询[l..r]的和
{
    if (a[k].l == a[k].r)
        return a[k].sum;
    else if (a[k].l == l && a[k].r == r)
        return a[k].sum;
    //else,要往下查询子节点,而lazy标记的影响还未必下传给了子节点,所以要下传lazy标记
    if (a[k].add)
        pushdown(k);
    int mid = (a[k].l + a[k].r) / 2;
    if (r <= mid)
        return query(k * 2, l, r);
    else if (l > mid)
        return query(k * 2 + 1, l, r);
    else
        return query(k * 2, l, mid) + query(k * 2 + 1, mid + 1, r);
}

|