线段树
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define ll long long #define ls k<<1 #define rs k<<1|1 struct tree { ll le,ri,sum,lz; } t[100100<<2]; inline void pushup(ll k) { t[k].sum=t[ls].sum+t[rs].sum; } inline void pushdown(ll k) { if(!t[k].lz)return ; t[ls].sum+=t[k].lz*(t[ls].ri-t[ls].le+1); t[rs].sum+=t[k].lz*(t[rs].ri-t[rs].le+1); t[ls].lz+=t[k].lz; t[rs].lz+=t[k].lz; t[k].lz=0; } ll n,m,a[100100]; inline void build(ll k,ll l,ll r) { t[k].le=l; t[k].ri=r; t[k].sum=t[k].lz=0; if(l==r) { t[k].sum=a[l]; return; } ll mid=l+r>>1; build(ls,l,mid); build(rs,mid+1,r); pushup(k); } inline void modify(ll k,ll l,ll r,ll v) { ll le=t[k].le,ri=t[k].ri; if(l==le&&r==ri) { t[k].sum+=v*(ri-le+1); t[k].lz+=v; return; } pushdown(k); ll mid=le+ri>>1; if(l>mid)modify(rs,l,r,v); else if(mid+1>r)modify(ls,l,r,v); else modify(ls,l,mid,v),modify(rs,mid+1,r,v); pushup(k); } inline ll query(ll k,ll l,ll r) { ll le=t[k].le,ri=t[k].ri; if(l==le&&r==ri) { return t[k].sum; } pushdown(k); ll mid=le+ri>>1; if(l>mid)return query(rs,l,r); else if(mid+1>r)return query(ls,l,r); else return query(ls,l,mid)+query(rs,mid+1,r); } int main() { scanf("%lld%lld",&n,&m); for(ll i=1; i<=n; i++)scanf("%d",&a[i]); build(1,1,n); for(ll i=1; i<=m; i++) { int o; scanf("%d",&o); if(o==1) { ll l,r,v; scanf("%lld%lld%lld",&l,&r,&v); modify(1,l,r,v); } else { ll l,r; scanf("%lld%lld",&l,&r); printf("%lld\n",query(1,l,r)); } } }