分析:花了大半天的时间才把成段更新的代码风格搞出来、说实话、不是很适应HH大牛的代码风格、于是自己写了一种容易理解的、自己把模板搞出来了、感觉做这类题就轻松多了、成段更新为了节约时间所以不能每次都更新到底、于是大牛们想到了用延迟标记来解决这个问题、当找到要更新的区间就标记它、等到下次要经过它的时候再继续向下更新、感觉很厉害的样子、呵呵
#include<stdio.h> #define N 100005 int n,ans; struct node{ int l,r; long long int sum; long long int mark;//增加一个延迟标记 }tree[N<<2]; long long int a[N]; void create(int x,int l,int r){ tree[x].l=l; tree[x].r=r; int mid=(l+r)/2; if(l==r){ tree[x].sum=a[l]; tree[x].mark=0; return; } create(x*2,l,mid); create(x*2+1,mid+1,r); tree[x].sum=tree[x*2].sum+tree[x*2+1].sum; } void update(int x,int l,int r,int num){ if(tree[x].l==l&&tree[x].r==r){ tree[x].mark+=num; return; } tree[x].sum+=num*(r-l+1); int mid=(tree[x].l+tree[x].r)/2; if(l>mid) update(x*2+1,l,r,num); else if(r<=mid) update(x*2,l,r,num); else{ update(x*2,l,mid,num); update(x*2+1,mid+1,r,num); } } void pushdown(int x){ if(tree[x].mark){ tree[x*2].mark+=tree[x].mark; tree[x*2+1].mark+=tree[x].mark; tree[x].sum+=(tree[x].r-tree[x].l+1)*tree[x].mark; tree[x].mark=0; } } long long int query(int x,int l,int r){ if(tree[x].l==l&&tree[x].r==r){ return tree[x].sum+tree[x].mark*(r-l+1); } pushdown(x); int mid=(tree[x].l+tree[x].r)/2; if(l>mid) return query(x*2+1,l,r); else if(r<=mid) return query(x*2,l,r); else { return query(x*2,l,mid)+query(x*2+1,mid+1,r); } } int main(){ long long int num; int m,x,y; char ch; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); create(1,1,n); while(m--){ scanf("%s",&ch); if(ch=='C'){ scanf("%d%d%lld",&x,&y,&num); update(1,x,y,num); } else if(ch=='Q'){ scanf("%d%d",&x,&y); printf("%lld\n",query(1,x,y)); } } return 0; }