#include<bits/stdc++.h>
using namespace std;
const double pi=3.14;
const int inf=0x3f3f3f3f;
const int NIL=-1;
#define f(i,l,r) for(int i=l;i<=r;i++)
struct Tree{
int l,r,mid;
int value;
int lazytag;
}T[100010];
int n,q;
int a[100010];
int sizex(int x){
return T[x].r-T[x].l+1;
}
void Pushup(int x){
T[x].value=T[x*2+1].value+T[x*2+1].value;
}
void pushdown(int x){
if (T[x].l<T[x].r){
T[x*2].lazytag+=T[x].lazytag;
T[x*2+1].lazytag+=T[x].lazytag;
//////////
T[x*2].value+=T[x*2].lazytag*sizex(x*2);
T[x*2+1].value+=T[x*2+1].lazytag*sizex(x*2+1);
//////////
T[x].lazytag=0;
}
}
void Prepare_Tree(int x,int l,int r){
T[x].l=l;
T[x].r=r;
T[x].lazytag=0;
if (l==r){
T[x].value=a[l];
}else{
T[x].mid=(l+r)/2;
Prepare_Tree(x*2,l,T[x].mid);
Prepare_Tree(x*2+1,T[x].mid+1,r);
Pushup(x);
}
}//建树 x为线段树上编号 l,r 为线段区间标记
void Update(int x,int l,int r,long long add){
if (T[x].l==l&&T[x].r==r){
T[x].value+=sizex(x)*add;
T[x].lazytag+=add;
return;
}
pushdown(x);
if (l>T[x].mid) Update(x*2+1,l,r,add);
else if (r<=T[x].mid) Update(x*2,l,r,add);
else{
Update(x*2,l,T[x].mid,add);
Update(x*2+1,T[x].mid+1,r,add);
}
Pushup(x);
}
long long Getsum(int x,int l,int r){
if (T[x].l==l&&T[x].r==r){
return T[x].value;
}
pushdown(x);
if (l>T[x].mid) return Getsum(x*2+1,l,r);
else if (r<=T[x].mid) return Getsum(x*2,l,r);
else{
long long res=0;
res+=Getsum(x*2,l,T[x].mid);
res+=Getsum(x*2+1,T[x].mid+1,r);
return res;
}
}
int read()
{
int ans=0,flag=1;
char ch=getchar();
while( (ch>'9' || ch<'0') && ch!='-' ) ch=getchar();
if(ch=='-') flag=-1,ch=getchar();
while(ch>='0' && ch<='9') ans=ans*10+ch-'0',ch=getchar();
return ans*flag;
}
int main()
{
n=read(),q=read();
for(int i=1;i<=n;i++)
a[i]=read();
Prepare_Tree(1,1,n);
for(int i=1;i<=q;i++){
int opt=read();
if(opt==1){
int f=read(),g=read();
long long h=read();
Update(1,f,g,h);
}else{
int f=read(),g=read();
long long res=Getsum(1,f,g);
cout<<res<<endl;
}
}
}
输入
5 5
1 5 4 2 3
2 2 4
1 2 3 2
2 3 4
1 1 5 1
2 1 4
输出
11
10
18