luogu_3372 【模板】線段樹 1
阿新 • • 發佈:2017-10-08
ons pushd int tdi sha brush iostream pda namespace
#include <cstdio> #include <iostream> using namespace std; const int N=1000010; int n,m; long long a[N],addv[N]; void pushdown(int o,int len){ if(addv[o]){ addv[o*2]+=addv[o]; addv[o*2+1]+=addv[o]; a[o*2]+=addv[o]*(len-len/2); a[o*2+1]+=addv[o]*(len/2); addv[o]=0; } return; } void pushup(int o){ a[o]=a[o*2]+a[o*2+1]; return; } void update(int l,int r,int L,int R,long long v,int o){ if(L<=l && r<=R){addv[o]+=v; a[o]+=v*(r-l+1); return;} pushdown(o,r-l+1); int mid=(l+r)>>1; if(mid>=L)update(l,mid,L,R,v,o*2); if(mid<R)update(mid+1,r,L,R,v,o*2+1); pushup(o); } long long query(int l,int r,int L,int R,int o){ long long ans=0; if(L<=l && r<=R)return a[o]; pushdown(o,r-l+1); int mid=(l+r)>>1; if(mid>=L)ans+=query(l,mid,L,R,o*2); if(mid<R)ans+=query(mid+1,r,L,R,o*2+1); return ans; } int main(){ int k=0; scanf("%d%d",&n,&m); while((1<<k)<n)k++; k=1<<k; for(int i=k;i<k+n;i++)scanf("%lld",&a[i]); for(int i=k-1;i;i--)a[i]=a[i*2]+a[i*2+1]; while(m--){ int x; scanf("%d",&x); if(x==1){ int l,r; long long v; scanf("%d%d%lld",&l,&r,&v); update(1,k,l,r,v,1); } else { int l,r; scanf("%d%d",&l,&r); printf("%lld\n",query(1,k,l,r,1)); } } return 0; }
luogu_3372 【模板】線段樹 1