原题传送门
#include
using namespace std;
const int N = 1000001;
typedef long long ll;
ll n,m,a[N],ans[N<<2],tag[N<<2];
inline ll leftSon(ll x)
{
return x<<1;
}
inline ll rightSon(ll x)
{
return x<<1|1;
}
inline void modifyUp(ll p)
{
ans[p]=ans[leftSon(p)]+ans[rightSon(p)];
}
inline void buildTree(ll p,ll l,ll r)
{
tag[p]=0;
if(l==r)
{
ans[p]=a[l];
return;
}
ll mid=(l+r)>>1;
buildTree(leftSon(p),l,mid);
buildTree(rightSon(p),mid+1,r);
modifyUp(p);
}
inline void addToRoot(ll p,ll l,ll r,ll k)
{
tag[p]+=k;
ans[p]+=k*(r-l+1);
}
inline void modifyDown(ll p,ll l,ll r)
{
ll mid=(l+r)>>1;
addToRoot(leftSon(p),l,mid,tag[p]);
addToRoot(rightSon(p),mid+1,r,tag[p]);
tag[p]=0;
}
inline void updateTree(ll newl,ll newr,ll l,ll r,ll p,ll k)
{
if(newl<=l&&r<=newr)
{
ans[p]+=k*(r-l+1);
tag[p]+=k;
return;
}
modifyDown(p,l,r);
ll mid=(l+r)>>1;
if(newl<=mid)
{
updateTree(newl,newr,l,mid,leftSon(p),k);
}
if(newr>mid)
{
updateTree(newl,newr,mid+1,r,rightSon(p),k);
}
modifyUp(p);
}
ll query(ll qx,ll qy,ll l,ll r,ll p)
{
ll res=0;
if(qx<=l&&r<=qy)
{
return ans[p];
}
ll mid=(l+r)>>1;
modifyDown(p,l,r);
if(qx<=mid)
{
res+=query(qx,qy,l,mid,leftSon(p));
}
if(qy>mid)
{
res+=query(qx,qy,mid+1,r,rightSon(p));
}
return res;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
ll n,m;
cin>>n>>m;
for(ll i=1;i<=n;i++)
{
cin>>a[i];
}
buildTree(1,1,n);
ll ask,b,c,d,e,f;
for(int k=1;k<=m;k++)
{
cin>>ask;
if(ask==1)
{
cin>>b>>c>>d;
updateTree(b,c,1,n,1,d);
}
else
{
cin>>e>>f;
cout<<query(e,f,1,n,1)<<endl;
}
}
}