线段树——区间修改、区间查询
模板
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e5+5; struct node { int l,r; ll sum,lazy; void update(ll x) { sum+=1ll*(r-l+1)*x; lazy+=x; } } tree[maxn<<2]; int n,a[maxn],q; void push_up(int x) { tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum; } void push_down(int x) { int lazyval=tree[x].lazy; if(lazyval) { tree[x<<1].update(lazyval); tree[x<<1|1].update(lazyval); tree[x].lazy=0; } } void build(int x,int l,int r) { tree[x].l=l,tree[x].r=r; tree[x].lazy=tree[x].sum=0; if(l==r) { tree[x].sum=a[l]; } else { int mid=(l+r)>>1; build(x<<1,l,mid); build(x<<1|1,mid+1,r); push_up(x); } } void update(int x,int l,int r,ll val) { int L=tree[x].l,R=tree[x].r; if(l<=L && R<=r) { tree[x].update(val); } else { push_down(x); int mid=(L+R)>>1; if(mid>=l)update(x<<1,l,r,val); if(mid<r)update(x<<1|1,l,r,val); push_up(x); } } ll query(int x,int l,int r) { int L=tree[x].l,R=tree[x].r; if(l<=L && R<=r) { return tree[x].sum; } else { push_down(x); ll ans=0; int mid=(L+R)>>1; if(mid>=l)ans+=query(x<<1,l,r); if(mid<r)ans+=query(x<<1|1,l,r); push_up(x); return ans; } } int main() { scanf("%d%d",&n,&q); for(int i=1; i<=n; i++) scanf("%d",&a[i]); build(1,1,n); for(int i=1; i<=q; i++) { int l,r,op; ll val; scanf("%d",&op); if(op==1) { scanf("%d%d%lld",&l,&r,&val); update(1,l,r,val); } else { scanf("%d%d",&l,&r); printf("%lld\n",query(1,l,r)); } } return 0; }