线段树

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=1e5+5;
ll n,m,a[maxn];
struct node{
    ll l,r,sum,tag;
}d[maxn<<2];
void pushup(ll p){
    d[p].sum=d[p*2].sum+d[p*2+1].sum;
}
void pushdown(ll p){
    d[p*2].sum+=d[p].tag*(d[p*2].r-d[p*2].l+1);
    d[p*2+1].sum+=d[p].tag*(d[p*2+1].r-d[p*2+1].l+1);
    d[p*2].tag+=d[p].tag;
    d[p*2+1].tag+=d[p].tag;
    d[p].tag=0;
}
void build(ll p,ll x,ll y){
    d[p].l=x;
    d[p].r=y;
    d[p].tag=0;
    if(x==y){
        d[p].sum=a[x];
        return;
    }
    ll mid=(x+y)/2;
    build(p*2,x,mid);
    build(p*2+1,mid+1,y);
    pushup(p);
}
void add(ll p,ll x,ll y,ll k){
    if(d[p].l>=x&&d[p].r<=y){
        d[p].sum+=k*(d[p].r-d[p].l+1);
        d[p].tag+=k;
        return;
    }
    pushdown(p);
    ll mid=(d[p].l+d[p].r)/2;
    if(mid>=x){
        add(p*2,x,y,k);
    }
    if(mid<y){
        add(p*2+1,x,y,k);
    }
    pushup(p);
}
ll query(ll p,ll x,ll y){
    if(d[p].l>=x&&d[p].r<=y){
        return d[p].sum;
    }
    pushdown(p);
    ll mid=(d[p].l+d[p].r)/2,ans=0;
    if(mid>=x){
        ans+=query(p*2,x,y);
    }
    if(mid<y){
        ans+=query(p*2+1,x,y);
    }
    return ans;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
    cin>>n>>m;
    for(ll i=1;i<=n;i++){
        cin>>a[i];
    }
    build(1,1,n);
    for(ll i=1;i<=m;i++){
        ll opt,x,y,k;
        cin>>opt>>x>>y;
        if(opt==1){
            cin>>k;
            add(1,x,y,k);
        }else{
            cout<<query(1,x,y)<<"\n";
        }
    }
    return 0;
}
posted @ 2026-10-17 16:26  beiciqi  阅读(2)  评论(0)    收藏  举报