线段树10分求助

P3372 【模板】线段树 1

__BAI__ @ 2023-01-12 21:48:56

#include<bits/stdc++.h>
using namespace std;
inline long long read(){
    long long x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9')
        x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int lazy[400005],tree[400005],n,a[100005],m,x,y,k,z;
void built(int d,int l,int r){
    if(l>=r)return;
    if(l==r-1){tree[d]=a[l];return;}
    int mid=(l+r)/2;
    int l_kid=d*2;
    int r_kid=d*2+1;
    built(l_kid,l,mid);
    built(r_kid,mid,r);
    tree[d]=tree[l_kid]+tree[r_kid];
}
void f(int d,int l,int r,int v){
    lazy[d]+=v;
    tree[d]+=v*(r-l); 
}
void add(int d,int l,int r,int p,int q,int v){
    if(p==l and q==r){f(d,l,r,v);return;}
    int mid=(l+r)/2;
    int l_kid=d*2;
    int r_kid=d*2+1;
    if(p>=mid)add(r_kid,mid,r,p,q,v);
    else if(q<=mid)add(l_kid,l,mid,p,q,v);
    else{
        add(l_kid,l,mid,p,mid,v);
        add(r_kid,mid,r,mid,q,v);
    }
    tree[d]=tree[l_kid]+tree[r_kid];
}
int get(int d,int l,int r,int p,int q){
    if(l==p and r==q){return tree[d];}
    int mid=(l+r)/2;
    int l_kid=d*2;
    int r_kid=d*2+1;
    if(lazy[d]){f(l_kid,l,mid,lazy[d]);f(r_kid,mid,r,lazy[d]);lazy[d]=0;}
    if(p>=mid)return get(r_kid,mid,r,p,q);
    if(q<=mid)return get(l_kid,l,mid,p,q);
    return get(l_kid,l,mid,p,mid)+get(r_kid,mid,r,mid,q);
}
int main(){
    n=read(),m=read();
    for(int i=1;i<=n;i++)
        a[i]=read();
    built(1,1,n+1);
    while(m--){
        z=read();
        if(z==1){
            x=read(),y=read(),k=read();
            add(1,1,n+1,x,y+1,k);
        }else{
            x=read(),y=read();
            printf("%d\n",get(1,1,n+1,x,y+1));
        }
    }
} 

by Rikora @ 2023-01-12 22:30:35

如果细节上没什么问题的话,是不是add的时候没有检查懒标记?add和get都应该在查询一个结点lazy不为0的时候把懒标记下推吧,代码里好像只有get下推了,add没下推,导致答案都偏小。


by Rikora @ 2023-01-12 22:54:47

刚才口胡了一下,删掉重发(

原因在于add在左右递归之后要把左右子节点的和重新赋值给父节点,如果之前父节点的懒惰标记没有推下去的话,此时左右子节点的值都是偏小的,它们的和也小于父节点正常的新值。


by __BAI__ @ 2023-01-13 08:12:53

好的,谢谢


|