玄关!0分求条

P3372 【模板】线段树 1

liuzilin114514 @ 2024-12-02 23:10:31

rt

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
ll a[100005],w[100005],k,len[100005],lzy[400020],x,y;
ll n,m;
ll type;
void pushup(ll x){
    w[x]=w[x<<1]+w[x<<1+1];
}
bool inc(ll l,ll r,ll L,ll R){
    return (L<=l)&&(r<=R);
}
bool all_not(ll l,ll r,ll L,ll R){
    return (l>R)||(r<L);
}
void maketag(ll len,ll x,ll u){
    lzy[u]+=x;
    w[u]+=len*x;
} 
void pushdown(ll L,ll R,ll u){
    ll mid=(L+R)>>1;
    maketag(mid-L+1,lzy[u],u*2);
    maketag(R-mid,lzy[u],u*2+1);
    lzy[u]=0;
}
void update1(ll L,ll R,ll l,ll r,ll u,ll x){
    if(inc(L,R,l,r))
        maketag(R-L+1,x,u);
    else if(!all_not(L,R,l,r)){
        ll mid=(L+R)/2;
        pushdown(L,R,u);
        update1(L,mid,l,r,u*2,x);
        update1(mid+1,R,l,r,u*2+1,x);
        pushup(u);
    }
} 
ll query1(ll L,ll R,ll l,ll r,ll u){
    if(inc(L,R,l,r))
        return w[u];
    else if(!all_not(L,R,l,r)){
        ll mid=(L+R)>>1;
        pushdown(L,R,u);
        return query1(L,mid,l,r,u*2)+query1(mid+1,R,l,r,u*2+1);
    }
    else    return 0;
}

//////////////////   华丽の分割线    ////////////////////// 

void found_tree(ll l,ll r,ll u){//建树 
    if(l==r){
        w[u]=a[l];
        return;
    }
    ll mid=(l+r)>>1;
    found_tree(l,mid,u*2);
    found_tree(mid+1,r,u*2+1);
    pushup(u);
}
void update(ll l,ll r,ll p,ll x,ll u){//单点赋值
    if(l==r){
        w[u]=x;
    }
    else{
        ll mid=(l+r)>>1;
        if(mid>=p)  update(l,mid,p,x,u*2);
        else    update(mid+1,r,p,x,u*2+1);  
        pushup(u);  
    }
} 
ll query(ll l,ll r,ll p,ll u){//单点查询 
    if(l==r){
        return w[u];
    }
    else{
        int mid=(l+r)>>1;
        if(mid>=p)  query(l,mid,p,u*2);
        else    query(mid+1,r,p,u*2+1); 
    }
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    for(ll i=1;i<=n;i++)    cin>>a[i];
    found_tree(1,n,1);
    while(m--){
        cin>>type;
        if(type==1){
            cin>>x>>y>>k;
            update1(1,n,x,y,1,k); 
        }
        else{
            cin>>x>>y;
            cout<<query1(1,n,x,y,1)<<'\n';
        }
    }
    return 0;
}

by piano_pei @ 2024-12-03 17:40:35

@liuzilin114514第八行,因为加法的运算优先级比位运算高,所以实际上x<<1+1=x<<2,应改为(x<<1)+1或x<<1|1


by liuzilin114514 @ 2024-12-03 21:42:50

@piano_pei THX,已关


|