区间修改,区间查询!
#include<iostream> #include<cstdio> using namespace std; int n,m,type; struct node{ int l,r;long long dis,flag; }tre[800001]; long long init() { long long x=0,f=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } void build(int now,int l,int r) { tre[now].l=l;tre[now].r=r; if(l==r) { tre[now].dis=init(); return; } int mid=(l+r)>>1; build(now<<1,l,mid); build(now<<1|1,mid+1,r); tre[now].dis=tre[now<<1].dis+tre[now<<1|1].dis; } void tree_flag(int now) { if(tre[now].r==tre[now].l) return; tre[now<<1].flag+=tre[now].flag; tre[now<<1|1].flag+=tre[now].flag; tre[now<<1].dis+=tre[now].flag*(tre[now<<1].r-tre[now<<1].l+1); tre[now<<1|1].dis+=tre[now].flag*(tre[now<<1|1].r-tre[now<<1|1].l+1); tre[now].flag=0; } void Change(int now,int l,int r,int k) { if(tre[now].l==l&&tre[now].r==r) { tre[now].dis+=(r-l+1)*k; tre[now].flag+=k; return; } if(tre[now].flag) tree_flag(now); int mid=(tre[now].l+tre[now].r)>>1; if(l>mid) Change(now<<1|1,l,r,k); else if(r<=mid) Change(now<<1,l,r,k); else { Change(now<<1,l,mid,k); Change(now<<1|1,mid+1,r,k); } tre[now].dis=tre[now<<1].dis+tre[now<<1|1].dis; } long long int Query(int now,int l,int r) { if(tre[now].l==l&&tre[now].r==r) { return tre[now].dis; } if(tre[now].flag)tree_flag(now); tre[now].dis=tre[now<<1].dis+tre[now<<1|1].dis; int mid=(tre[now].l+tre[now].r)>>1; if(l>mid)return Query(now<<1|1,l,r); else if(r<=mid)return Query(now<<1,l,r); else { return Query(now<<1,l,mid)+Query(now<<1|1,mid+1,r); } } int main() { n=init(); build(1,1,(int)n); m=init(); long long int l,r,x; for(int i=1;i<=m;i++) { type=init(); if(type==1) { l=init(),r=init(),x=init(); Change(1,(int)l,(int)r,(int)x); } else { l=init(),r=init(); printf("%lld ",Query(1,(int)l,(int)r)); } } return 0; }