#include <cstdio> #include <cstring> #include <cmath> #include <string> #include <sstream> #include <cstdlib> #include <algorithm> #include <iostream> #include <set> #include <map> #include <vector> #include <queue> #include <stack> #include <functional> using namespace std; #define ll long long #define re register #define mp make_pair #define fi first #define se second #define pb push_back #define P pair<int,int> const int N=1e6+10; void read(ll &a) { int d=1; char ch; a=0; while(ch=getchar(),!isdigit(ch)) if(ch=='-') d=-1; a=ch^48; while(ch=getchar(),isdigit(ch)) a=(a<<3)+(a<<1)+(ch^48); a*=d; } void write(ll x) { if(x<0) putchar(45),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); } ll ans[N<<1],a[N],tag[N<<1]; ll ls(ll i){return i<<1;}///左儿子 ll rs(ll i){return i<<1|1;}///右儿子 void push_up(ll p){ans[p]=ans[ls(p)]+ans[rs(p)];}///区间合并 void built(ll p,ll l,ll r) { if(l==r) { ans[p]=a[l]; return; } ll mid=(l+r)>>1; built(ls(p),l,mid); built(rs(p),mid+1,r); push_up(p);///回溯时做区间合并 } void f(ll p,ll l,ll r,ll k) { tag[p]+=k; ans[p]+=(r-l+1)*k; } void push_down(ll p,ll l,ll r) { ll mid=(l+r)>>1; f(ls(p),l,mid,tag[p]);///将父节点所带的值加到子区间去 f(rs(p),mid+1,r,tag[p]); tag[p]=0;///然后父节点的值归0 } void update(ll nl,ll nr,ll l,ll r,ll p,ll k) { if(nl<=l&&r<=nr)///包含整个区间,直接加就完事 { ans[p]+=(r-l+1)*k; tag[p]+=k; return; } push_down(p,l,r);///将该父节点的值放入子区间 ll mid=(l+r)>>1; if(nl<=mid) update(nl,nr,l,mid,ls(p),k); if(nr>mid) update(nl,nr,mid+1,r,rs(p),k); push_up(p);///合并区间 } ll query(ll nl,ll nr,ll l,ll r,ll p) { ll res=0; if(nl<=l&&r<=nr) return ans[p]; ll mid=(l+r)>>1; push_down(p,l,r); if(nl<=mid) res+=query(nl,nr,l,mid,ls(p)); if(nr>mid) res+=query(nl,nr,mid+1,r,rs(p)); return res; } int main() { //freopen("out.txt","w",stdout); ll n,T; read(n); read(T); for(re ll i=1;i<=n;i++) read(a[i]); built(1,1,n); while(T--) { ll f; read(f); if(f==1) { ll l,r,k; read(l); read(r); read(k); update(l,r,1,n,1,k); } else { ll l,r; read(l); read(r); write(query(l,r,1,n,1)); putchar(' '); } } return 0; }