线段树区间更新 lazy思想
lazy-tag 记录每一个线段树节点的变化值,当这部分线段的一致性被破坏后,我们就将这个变化值传给他的子区间
比如说: 我们对于区间【a,b】进行加c的更新操作,从根节点开始进行update,如果现在执行到子节点rt,这时候
tree[rt].l==a&&tree[rt].r==b;这个时候我们可以进一步更新此时rt节点的sum[rt]的值,sum[rt] += c* (tree[rt].r - tree[rt].l + 1)
!!!这个时候我们要进行update操作去更新rt子节点的sum[]值,但是我们懒(lazy)orz,我们lazy的思想就是暂时不更新
rt子节点的sum[]值,到此return,我们到下次需要用到rt子节点的值的时候再去更新,这样节省时间。
pushdown(rt):通过当前节点rt递归向下去更新rt子节点的值
结合上次https://blog.csdn.net/qq_37748451/article/details/81104452 这个题线段更新的代码我们来看一下
void pushdown(int rt){
putTag(rt*2,mx[rt]);
putTag(rt*2+1,mx[rt]);
}
void change(int L,int R,int rt,int l,int r,int x){
if (x>=mx[rt])
return;
if (L<=l&&R>=r&&se[rt]<x){
putTag(rt, x);
return;
}
pushdown(rt);
if (L <= (l + r) / 2) change(L, R,rt*2,l,(l+r)/2, x);
if (R > (l + r) / 2) change(L, R,rt*2+1,(l+r)/2+1,r, x);
pushup(rt);
}
当我们执行change操作的时候,如果上述满足if条件的时候 就用到lazy啦
这里应该首先putTag这个点就足够了,函数就运行完了,直接return,这样就运行完了
而不是还继续向子节点继续更新,这就是lazy思想,暂不更新子节点的值
什么时候需要更新呢,
下面,在某部分更新的时候需要用到那部分没有更新的结点的时候,就用pushdown()
pushdown更新的是根节点的左右节点,(应该是只有这两个会更新,而不继续向下)。