线段树lazy
来看一道线段树模板题,
看完题目就知道是一个线段树的模板题,再看下数据范围,1e5,就知道如果直接暴力修改的话那么肯定超时,
所以用了lazy标记,先标记再修改,初始化的时候先把lazy置为0,如果发现区间有修改的情况,那么先把这个结点更新一下,
再把这个结点lazy标记一下,如果查询lazy不为0的结点的话那么就把lazy更新到子节点上,这样就不用每次都更新所有结点了,具体看code。
蒟蒻的代码(水过):
#include<iostream> using namespace std; typedef long long LL; const int MAX=1e5+10; struct node { int l; int r; LL val; LL lazy; }nodes[4*MAX]; int inv; void push(int x){ nodes[x].val=nodes[x<<1].val+nodes[x<<1|1].val; } void pushdown(int x){ if(nodes[x].lazy!=0){ int mid=nodes[x].l+nodes[x].r>>1; nodes[x<<1].lazy+=nodes[x].lazy; nodes[x<<1|1].lazy+=nodes[x].lazy; nodes[x<<1].val+=(mid-nodes[x].l+1)*nodes[x].lazy; nodes[x<<1|1].val+=(nodes[x].r-mid)*nodes[x].lazy; nodes[x].lazy=0; } } void build(int root,int ll,int rr){ nodes[root].lazy=0; nodes[root].l=ll; nodes[root].r=rr; if(ll==rr){ cin>>inv; nodes[root].val=inv; } if(ll>=rr)return ; int mid=(ll+rr)>>1; build((root<<1),ll,mid); build((root<<1)|1,mid+1,rr); push(root); } void add(int root,int ll, int rr,int val){ if(ll>nodes[root].r||rr<nodes[root].l)return ; if(ll<=nodes[root].l&&rr>=nodes[root].r){ nodes[root].lazy+=val; nodes[root].val+=(nodes[root].r-nodes[root].l+1)*val; return; } pushdown(root); int mid=(nodes[root].l+nodes[root].r)>>1; if(ll<=mid)add(root<<1,ll,rr,val); if(rr>mid)add(root<<1|1,ll,rr,val); push(root); } LL query(int root,int ll,int rr){ if(rr<nodes[root].l||ll>nodes[root].r)return 0; if(ll<=nodes[root].l&&rr>=nodes[root].r){ return nodes[root].val; } pushdown(root); int mid=(nodes[root].l+nodes[root].r)>>1; LL leftval=0,rightval=0; if(ll<=mid)leftval=query(root<<1,ll,rr); if(rr>mid)rightval=query(root<<1|1,ll,rr); return leftval+rightval; } int main(){ int n,m; cin>>n>>m; build(1,1,n); while(m--){ char c; cin>>c; if(c=='Q'){ int l,r; cin>>l>>r; cout<<query(1,l,r)<<endl; } else { int l,r,v; cin>>l>>r>>v; add(1,l,r,v); } } return 0; }
总结:以后还是找个大佬的板子比较好,自己的板子太水了QAQ。

浙公网安备 33010602011771号