这次是真的线段树
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,q;
inline int read() {
int ret=0,f=1;
char c=getchar();
for(; c<'0'||c>'9'; c=getchar()) if(c=='-') f=-f;
for(; c>='0'&&c<='9'; c=getchar()) ret=ret*10+c-'0';
return ret*f;
}
const int maxn=5e5+10;
int input[maxn];
struct TREE {
int l,r,num,lz;
} tree[maxn*4];
void init(int i,int l,int r) {
tree[i].l=l;
tree[i].r=r;
tree[i].lz=0;
if(l==r) {
tree[i].num=input[l];
return;
}
int mid=(l+r)/2;
init(i*2,l,mid);
init(i*2+1,mid+1,r);
tree[i].num=tree[i*2].num+tree[i*2+1].num;
return;
}
void push_down(int i){
if(tree[i].lz!=0){
tree[i*2].lz+=tree[i].lz;
tree[i*2+1].lz+=tree[i].lz;
int mid=(tree[i].l+tree[i].r)/2;
tree[i*2].num+=tree[i].lz*(mid-tree[i*2].l+1);
tree[i*2+1].num+=tree[i].lz*(tree[i].r-mid);
tree[i].lz=0;
}
return;
}
void up_data(int i,int l,int r,int k){
if(tree[i].r<=r && tree[i].l>=l){
tree[i].num+=k*(tree[i].r-tree[i].l+1);
tree[i].lz+=k;
return;
}
push_down(i);
if(tree[i*2].r>=l){
up_data(i*2,l,r,k);
}
if(tree[i*2+1].l<=r){
up_data(i*2+1,l,r,k);
}
tree[i].num=tree[i*2].num+tree[i*2+1].num;
}
int search(int i,int l,int r){
if(tree[i].l>=l&&tree[i].r<=r){
return tree[i].num;
}
push_down(i);
int number=0;
if(tree[i*2].r>=l){
number+=search(i*2,l,r);
}
if(tree[i*2+1].l<=r){
number+=search(i*2+1,l,r);
}
return number;
}
signed main(void) {
n=read();
q=read();
init(1,1,n);
for(int i=1; i<=n; i++) {
input[i]=read();
}
for(int i=1; i<=q; i++) {
int t;
t=read();
if(t==1) {
int x,y,k;
x=read();y=read();k=read();
up_data(1,x,y,k);
} else {
int u,v;
u=read();v=read();
cout<<search(1,u,v)<<endl;
}
}
return 0;
}