在开始这个话题之前,先简略说明一下单个lazy标记的作用与意义(想详尽了解的话自行百度一下,有很多)。
lazy标记
- 作用:降低区间操作的复杂度
- 意义:lazy标记表示已对当前节点进行了相应修改,而暂时没有对其左右子节点进行修改
- 注意:一旦打了标记就要修改当前节点的值,标记只表明未修改其左右子节点,而非未修改当前节点。
双重标记
一些题有多种区间修改方式,仅用一个标记并不能很好的维护;不过,有了单个标记的思想,就可以将其拓展到多个标记了。
问题引入
多重标记中最常见的就是双重标记。每个标记的作用、意义都与单个标记时无异。当两个标记互不影响时,我们只需要按照单个标记那样一个个处理就好了,这里不再赘述。不过,当两个标记互相之间有影响时,会出现一个问题:两个标记的修改顺序是怎样的呢?以bzoj1798为例,假设线段树中的某个节点有一个区间加标记,还有一个区间乘标记,那么在修改及下放标记时,应该先加后乘,还是先乘后加呢(显然,这两种不同的操作会得到不同的解)?
思考
既然顺序不清,不妨就定义一个优先级吧!仍以上题为例:
定义同时存在两个标记时表示先乘后加。那么:
- 对一个无标记的节点打加标记:直接打上加标记,同时更新sum值
- 对一个无标记的节点打乘标记:直接打上乘标记,同时更新sum值
- 对一个已有乘