带有lazy标记的线段树
Posted cc123321
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了带有lazy标记的线段树相关的知识,希望对你有一定的参考价值。
#include<bits/stdc++.h> using namespace std; int n,m,x,y,val,com,s[100000]; struct st{ int l,r,val,add; }tr[10000000]; void build(int l,int r,int k) { tr[k].l=l; tr[k].r=r; if(l==r) { tr[k].val=s[l]; return; } int mid=(l+r)>>1; build(l,mid,k<<1); build(mid+1,r,k<<1|1); tr[k].val = tr[k<<1].val + tr[k<<1|1].val; } void pus(int k) { int l=tr[k].l; int r=tr[k].r; tr[k].add+=tr[k>>1].add; tr[k].val+=(r-l+1)*tr[k>>1].add; } void update(int x,int y,int k,int val) { if(tr[k].add) { pus(k<<1); pus(k<<1|1); tr[k].add=0; } int l=tr[k].l; int r=tr[k].r; int mid=(l+r)>>1; if(y<l || x>r) return; if(x<=l && r<=y) { tr[k].val += (l-r+1)*val; tr[k].add += val; return; } else { if(x<=mid) update(x,y,k<<1,val); if(y>mid) update(x,y,k<<1|1,val); tr[k].val = tr[k<<1].val + tr[k<<1|1].val; } } int sum(int x,int y,int k) { if(tr[k].add) { pus(k<<1); pus(k<<1|1); tr[k].add=0; } int l=tr[k].l; int r=tr[k].r; int mid=(l+r)>>1; if(y<l || x>r) return 0; if(x<=l && r<=y) return tr[k].val; else { int ans=0; if(x<=mid) ans+=sum(x,y,k<<1); if(y>mid) ans+=sum(x,y,k<<1|1); return ans; } } main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&s[i]); build(1,n,1); while(m--) { scanf("%d",&com); if(com==1) { scanf("%d%d%d",&x,&y,&val); update(x,y,1,val); } else { scanf("%d%d",&x,&y); printf("%d\n",sum(x,y,1)); } } }
以上是关于带有lazy标记的线段树的主要内容,如果未能解决你的问题,请参考以下文章