#include<iostream>
#define lc k<<1
#define rc k<<1|1
#define int long long
using namespace std;
const int N=1e7+5;
int a[N],n,m;
struct node{
    int l,r,v,lazy;
}tree[N];
void pushdown(int k){//下传懒标记
    if(tree[k].lazy!=0){
        tree[lc].lazy+=tree[k].lazy;//下传左子树
        tree[rc].lazy+=tree[k].lazy;//下传右子树
        tree[lc].v+=tree[k].lazy*(tree[lc].r-tree[lc].l+1);//更新左子树sum
        tree[rc].v+=tree[k].lazy*(tree[rc].r-tree[rc].l+1);//更新右子树sum
        tree[k].lazy=0;//清空懒标记
    }
}
void build(int k,int l,int r){//建树
    tree[k].l=l;
    tree[k].r=r;
    tree[k].lazy=0;
    if(l==r){//到达叶子节点
        tree[k].v=a[l];
        return;
    }
    int mid=(l+r)/2;
    build(lc,l,mid);
    build(rc,mid+1,r);
    tree[k].v=tree[lc].v+tree[rc].v;
}
void update(int k,int l,int r,int w){//区间更新
    if(tree[k].l>=l&&tree[k].r<=r){
        tree[k].v+=w*(tree[k].r-tree[k].l+1);
        tree[k].lazy+=w;//更新懒标记
        return;
    }
    pushdown(k);
    int mid=(tree[k].l+tree[k].r)/2;
    if(l<=mid)
        update(lc,l,r,w);
    if(r>mid)
        update(rc,l,r,w);
    tree[k].v=tree[lc].v+tree[rc].v;
}
int find_sum(int k,int l,int r){
    if(tree[k].l>=l&&tree[k].r<=r)
        return tree[k].v;
    pushdown(k);
    int mid=(tree[k].l+tree[k].r)/2,res=0;
    if(l<=mid)
        res+=find_sum(lc,l,r);
    if(r>mid)
        res+=find_sum(rc,l,r);
    return res;
}
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,1,n);
    for(int i=1;i<=m;i++){
        int flag,ll,rr,vv;
        cin>>flag>>ll>>rr;
        if(flag==1){
            cin>>vv;
            update(1,ll,rr,vv);
        }
        else
            cout<<find_sum(1,ll,rr)<<'\n';
    }
    return 0;
}

讨论节点