以上摘自LYH大佬课件;
可以实现:
1.区间加;
2.查询区间和;
粘代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 typedef long long ll; 6 using namespace std; 7 const int maxn=100009; 8 struct node{ 9 ll l,r,sum,lazy; 10 }tr[maxn<<2]; 11 ll a[maxn],n,m; 12 void build_(ll p,ll l,ll r)//建树 13 { 14 tr[p].l=l; 15 tr[p].r=r; 16 if(l==r) 17 { 18 tr[p].sum=a[l]; 19 return ; 20 } 21 ll mid=(l+r)>>1; 22 build_(p<<1,l,mid); 23 build_(p<<1|1,mid+1,r); 24 tr[p].sum=tr[p<<1].sum+tr[p<<1|1].sum; 25 } 26 void add_(ll p,ll l,ll r,ll d)//区间加 27 { 28 if(tr[p].l==l&&tr[p].r==r) 29 { 30 tr[p].sum+=d*(r-l+1); 31 tr[p].lazy+=d; 32 return ; 33 } 34 ll mid=(tr[p].l+tr[p].r)>>1; 35 if(tr[p].lazy)//lazy下传 36 { 37 add_(p<<1,tr[p<<1].l,tr[p<<1].r,tr[p].lazy); 38 add_(p<<1|1,tr[p<<1|1].l,tr[p<<1|1].r,tr[p].lazy); 39 tr[p].lazy=0; 40 } 41 if(r<=mid) add_(p<<1,l,r,d); 42 else if(l>mid) add_(p<<1|1,l,r,d); 43 else 44 { 45 add_(p<<1,l,mid,d); 46 add_(p<<1|1,mid+1,r,d); 47 } 48 tr[p].sum=tr[p<<1].sum+tr[p<<1|1].sum;//记得要上传新值 49 } 50 ll ask_(ll p,ll l,ll r)//询问区间和 51 { 52 if(tr[p].l==l&&tr[p].r==r) return tr[p].sum; 53 if(tr[p].lazy)//下传lazy标记 54 { 55 add_(p<<1,tr[p<<1].l,tr[p<<1].r,tr[p].lazy); 56 add_(p<<1|1,tr[p<<1|1].l,tr[p<<1|1].r,tr[p].lazy); 57 tr[p].lazy=0; 58 } 59 ll sum=0; 60 ll mid=(tr[p].l+tr[p].r)>>1; 61 if(r<=mid) sum+=ask_(p<<1,l,r); 62 else if(l>mid) sum+=ask_(p<<1|1,l,r); 63 else 64 { 65 sum+=ask_(p<<1,l,mid); 66 sum+=ask_(p<<1|1,mid+1,r); 67 } 68 return sum; 69 } 70 int main() 71 { 72 scanf("%lld%lld",&n,&m); 73 for(int i=1;i<=n;i++) scanf("%lld",&a[i]); 74 build_(1,1,n); 75 for(int i=1;i<=m;i++) 76 { 77 ll aa,bb,cc,k; 78 scanf("%lld",&aa); 79 if(aa==1) 80 { 81 scanf("%lld%lld%lld",&bb,&cc,&k); 82 add_(1,bb,cc,k); 83 } 84 if(aa==2) 85 { 86 scanf("%lld%lld",&bb,&cc); 87 printf("%lld ",ask_(1,bb,cc)); 88 } 89 } 90 return 0; 91 }
感谢GMK大佬的帮助。