#include<bits/stdc++.h>
using namespace std;
#define N 114514
#define int long long
long long a[N];
struct nod{
int l,r;
int value;
int add;
}tree[5*N];
void build(int l,int r,int i){
tree[i]={l,r,0,0};
//cout<<l<<" "<<r<<endl;
if(l==r){
tree[i].value=a[l];
return;
}
int mid=l+(r-l)/2;
build(l,mid,i*2);
build(mid+1,r,i*2+1);
tree[i].value=tree[i*2].value+tree[i*2+1].value;
}
void spr(int i){
tree[i*2].value+=tree[i].add*(tree[i*2].r-tree[i*2].l+1);
tree[i*2+1].value+=tree[i].add*(tree[i*2+1].r-tree[i*2+1].l+1);
tree[i*2].add+=tree[i].add;
tree[i*2+1].add+=tree[i].add;
tree[i].add=0;
}
long long getsum(int l,int r,int i){
if(tree[i].r<l||tree[i].l>r)return 0;
if(tree[i].l>=l&&tree[i].r<=r)return tree[i].value;
spr(i);
return getsum(l,r,i*2)+getsum(l,r,i*2+1);
}
void add(int l,int r,int i,int data){
if(tree[i].r<l||tree[i].l>r)return;
if(tree[i].l>=l&&tree[i].r<=r){
tree[i].value+=data*(tree[i].r-tree[i].l+1);
tree[i].add+=data;
return;
}
tree[i].value+=data*(min(tree[i].r,r)-max(tree[i].l,l)+1);
spr(i);
add(l,r,i*2,data);
add(l,r,i*2+1,data);
}
signed main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
build(1,n,1);
while(m--){
//for(int i=1;i<=4*n+5;i++)cout<<tree[i].l<<" "<<tree[i].r<<":"<<tree[i].value<<" "<<tree[i].add<<endl;cout<<endl;
int q;
scanf("%d",&q);
int x,y;
scanf("%d%d",&x,&y);
if(q==1){
int k;
scanf("%d",&k);
add(x,y,1,k);
}
else printf("%d\n",getsum(x,y,1));
}
}
一般思路的线段树