线段树一个区间进行多个操作时处理的优先级
** 懒惰标记:当前区间已经修改,但儿子节点区间未修改,不能误认为当前区间也未修改。**
一 、 区间赋值和区间加值
这个很明显就是赋值的优先级高,下放懒惰标记时,我们做出如下讨论。
- 当前区间有赋值标记时,对儿子区间进行赋值,同时标记传给儿子,把当前区间以及儿子区间的加标记清除
- 当前区间无懒惰标记,但有加标记,对儿子区间进行修改,同时标记下传, 下传时注意。若儿子区间有赋值标记,此时需要将儿子区间的赋值标记加上当前的加标记的值,同时将可儿子区间加标记清除。若儿子区间无赋值标记,直接将加标记下传即可。
修改也有如下讨论
- 执行赋值修改时,区间打上赋值标记时,将加标记清除
- 执行加值修改时,如当前区间有赋值标记,则在赋值标记上加上当前的加值,若无赋值标记,区间加上加值标记即可。
void PushDown(int rt){
if (changetag[rt] != -1){
Max[rt<<1] = changetag[rt]; Max[rt<<1|1] = changetag[rt];
changetag[rt << 1] = changetag[rt]; addtag[rt << 1] = 0;
changetag[rt << 1 | 1] = changetag[rt]; addtag[rt << 1 | 1] = 0;
changetag[rt] = -1;
}else if (addtag[rt]){
Max[rt<<1] += addtag[rt]; Max[rt<<1|1] += addtag[rt];
if (changetag[rt<<1] != -1) changetag[rt<<1] += addtag[rt];
else addtag[rt<<1] += addtag[rt];
if (changetag[rt<<1|1] != -1) changetag[rt<<1|1] += addtag[rt];
else addtag[rt<<1|1] += addtag[rt];
addtag[rt] = 0;
}
}
void add(int rt, int l, int r, int L, int R, int C)
{
if (L <= l && r <= R){
Max[rt] = Max[rt] + C;
if (changetag[rt] == -1) addtag[rt] += C;
else changetag[rt] += C;
return;
}
}
void change()
{
}
评论