刚学线段树1ms蒟蒻求调

P3372 【模板】线段树 1

nightwatch.ryan @ 2024-07-31 20:58:38

rt,样例都没过,看了好久都没看出来

#include<iostream>
#define N 100005
using ll=long long;
ll a[N],sum[N*4],tag[N*4];
inline bool chkall(int L,int R,int l,int r){return (l<=L&&R<=r);}
inline bool chkno(int L,int R,int l,int r){return (L>r||R<l);}
inline void pushup(const int&i){sum[i]=sum[i<<1]+sum[(i<<1)+1];}
inline void build(const int&i,int l,int r){
    if(l==r)return sum[i]=a[l],void();
    int mid=(l+r)>>1;
    build(i<<1,l,mid),build((i<<1)+1,mid+1,r);
    pushup(i);
}
inline ll query(int i,int L,int R,int l,int r){
    if(chkall(L,R,l,r))return sum[i];
    else if(!chkno(L,R,l,r)){
        int mid=(L+R)>>1;
        return query(i<<1,L,mid,l,r)+query((i<<1)+1,mid+1,R,l,r);
    } else return 0;
}
void makeTag(int i,int length,ll v){tag[i]+=v,sum[i]+=length*v;}
void pushdown(int i,int l,int r){
    int mid=(l+r)>>1;
    makeTag(i<<1,mid-l+1,tag[i]);
    makeTag((i<<1)+1,r-mid,tag[i]);
    tag[i]=0;
}
void update(int i,int L,int R,int l,int r,ll v){
    if(chkall(L,R,l,r)){
        makeTag(i,R-L+1,v);
    }else if(!chkno(L,R,l,r)){
        int mid=(L+R)>>1;
        pushdown(i,L,R);
        update(i<<1,L,mid,l,r,v);
        update((i<<1)+1,mid+1,R,l,r,v);
        pushup(i);
    }
}
int main(){
    int n,m;
    std::cin>>n>>m;
    for(int i=1;i<=n;i++)std::cin>>a[i];
    build(1,1,n);
    while(m--){
        int op,x,y;
        std::cin>>op>>x>>y;
        if(op==1){
            ll v;
            std::cin>>v;
            update(1,1,n,x,y,v);
        }else{
            std::cout<<query(1,1,n,x,y)<<std::endl;
        }
    }
}

by nightwatch.ryan @ 2024-07-31 21:01:14

样例输出

11 
8 
20

我的输出

11
8
16

by Michaellg @ 2024-07-31 21:02:21

@nightwatch_ryan query 没有 pushdown


by nightwatch.ryan @ 2024-07-31 21:03:01

@Michaellg 感谢 dalao,关注了


|