这个可以作为线段树的模板来使用了,很经典,以前总是搞不清楚要向下更新,这次是明白了,多次修改很多区间时没必要每次都去修改,可以最后一块修改
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stdio.h> 2 #include<string.h> 3 #define N 100005 4 struct node 5 { 6 int r,l; 7 long long sum,v; 8 }; 9 node p[4*N]; 10 long long val[N]; 11 void build(int l,int r,int i) 12 { 13 p[i].r=r; 14 p[i].l=l; 15 p[i].v=p[i].sum=0; 16 if(r==l) 17 { 18 //p[i].v=val[i]; 19 p[i].sum=val[l]; 20 return; 21 } 22 int mid=(l+r)>>1; 23 build(l,mid,i<<1); 24 build(mid+1,r,i<<1|1); 25 p[i].sum=p[i<<1].sum+p[i<<1|1].sum; 26 } 27 void update(int l,int r,int v,int i) 28 { 29 if(p[i].r==r&&p[i].l==l) 30 { 31 p[i].sum+=(v*(r-l+1)); 32 p[i].v+=v; 33 return; 34 } 35 if(p[i].v) 36 { 37 p[i<<1].v+=p[i].v; 38 p[i<<1|1].v+=p[i].v; 39 p[i<<1].sum+=(p[i].v*(p[i<<1].r-p[i<<1].l+1)); 40 p[i<<1|1].sum+=(p[i].v*(p[i<<1|1].r-p[i<<1|1].l+1)); 41 p[i].v=0; 42 } 43 int mid=(p[i].r+p[i].l)>>1; 44 if(r<=mid) 45 update(l,r,v,i<<1); 46 else if(mid<l) 47 update(l,r,v,i<<1|1); 48 else 49 { 50 update(l,mid,v,i<<1); 51 update(mid+1,r,v,i<<1|1); 52 } 53 p[i].sum=p[i<<1].sum+p[i<<1|1].sum; 54 //printf("%d %d\n",i,p[i].sum); 55 } 56 long long query(int l,int r,int i) 57 { 58 if(p[i].l==l&&p[i].r==r) 59 return p[i].sum; 60 if(p[i].v) 61 { 62 p[i<<1].v+=p[i].v; 63 p[i<<1|1].v+=p[i].v; 64 p[i<<1].sum+=(p[i].v*(p[i<<1].r-p[i<<1].l+1)); 65 p[i<<1|1].sum+=(p[i].v*(p[i<<1|1].r-p[i<<1|1].l+1)); 66 p[i].v=0; 67 } 68 int mid=(p[i].l+p[i].r)>>1; 69 if(r<=mid) 70 return query(l,r,i<<1); 71 else if(mid<l) 72 return query(l,r,i<<1|1); 73 return query(l,mid,i<<1)+query(mid+1,r,i<<1|1); 74 } 75 int main() 76 { 77 int n,i,m; 78 int a,b; 79 long long c; 80 char ch[2]; 81 while(~scanf("%d%d",&n,&m)) 82 { 83 for(i=1;i<=n;i++) 84 scanf("%lld",&val[i]); 85 build(1,n,1); 86 //printf("%d\n",p[1].sum); 87 while(m--) 88 { 89 scanf("%s%d%d",ch,&a,&b); 90 if(ch[0]=='C') 91 { 92 scanf("%lld",&c); 93 update(a,b,c,1); 94 } 95 else 96 { 97 printf("%lld\n",query(a,b,1)); 98 } 99 } 100 } 101 return 0; 102 }