code:
#include <bits/stdc++.h>
#include <algorithm>
#include <bitset>
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <limits>
#include <list>
#include <map>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <cstring>
#define int long long
#include <utility>
#include <vector>
#include <cwchar>
#include <cwctype>
#include <complex.h>
#include <fenv.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdint.h>
#include <tgmath.h>
using namespace std;
const int N=131072+10;
int a[100010];
struct Segmenttree{
int w[N];
int tag[N];
int l[N];
int r[N];
void pushdown(int n){
w[n*2]+=tag[n]*(r[n*2]-l[n*2]+1);
w[n*2+1]+=tag[n]*(r[n*2+1]-l[n*2+1]+1);
tag[n*2]+=tag[n];
tag[n*2+1]+=tag[n];
tag[n]=0;
}
int query(int L,int R,int u){
if(L<=l[u]&&r[u]<=R){
return w[u];
}
else if(R<l[u]||L>r[u]) return 0;
else{
pushdown(u);
return query(L,R,u*2)+query(L,R,u*2+1);
}
}
void change(int L,int R,int u,int k){
if(R<l[u]||L>r[u]) return ;
else if(L<=l[u]&&r[u]<=R){
tag[u]+=k;
w[u]+=(r[u]-l[u]+1)*k;
}
else{
change(L,R,u*2,k);
change(L,R,u*2+1,k);
}
}
void build(int n){
if(l[n]==r[n]){
w[n]=a[l[n]];
return ;
}
int Mid=(l[n]+r[n])>>1;
l[n*2]=l[n];
r[n*2]=Mid;
l[n*2+1]=Mid+1;
r[n*2+1]=r[n];
build(n*2);
build(n*2+1);
w[n]=w[n*2]+w[n*2+1];
}
}tree;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,m;
cin>>n>>m;
tree.l[1]=1;
tree.r[1]=n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
tree.build(1);
while(m--){
int type;
cin>>type;
if(type==1){
int x,y,k;
cin>>x>>y>>k;
tree.change(x,y,1,k);
}
else{
int x,y;
cin>>x>>y;
cout<<tree.query(x,y,1)<<'\n';
}
}
return 0;
}