Space Harbour

非常好的一道练习懒标记的题目(这种题目就叫做多标记题目)

我们先不考虑维护总和,先分别维护两个量,\(value\)表示\(p\)号节点所代表区间的点的权值,\(dis\)表示\(p\)号节点所代表区间的点的距离和,\(lazy\)表示\(p\)号节点权值的懒标记,\(dislazy\)表示\(p\)号节点距离增量的懒标记

那么对于\(dis\)\(dislazy\)来说就跟一般的维护区间加减一样了,非常简单

对于\(value\)\(lazy\)来说,\(p\)节点所代表区间的权值可能不完全一样,这是这道题目最大的难点;如果说我们不考虑维护题目所要求的总和,只是维护一个权值,那么如果\(p\)所代表区间的所有点的权值都一样,那么\(value\)就为这个权值,否则的话\(value\)\(0\);然后这里跟"Atlantis"的维护非常像,我们就只考虑叶子节点,一个叶子节点真正的权值就是从这个叶子节点往根节点走,最后一个\(lazy\)所代表的权值

然后我们考虑维护题目所要求的总和

注意这里有两个标记需要下传,无论哪个标记下传(还是说两个都要下传),我们都要保证即将往子节点更新的时候,子节点的所有的量都已经被维护成了除了这次操作的最新的值(就是说比如这次操作是第\(k\)次操作,我们即将进入某一个节点\(q\),那么进入的时候一定要保证\(q\)的所有的量是第\(k-1\)次操作之后的最新的值),并且在下传完之后,要保证子节点的值是包含这次操作的最新的值

那我们来看看这些量是否已经可以达到上述要求

我们先随意假设一个优先级,就假设权值的更新优先于距离的更新吧

假设现在\(lazy\)要下传,那么考虑\(sum\)如何变化,显然就是\(sum=lazy\times dis\)(其中\(dis\)是子节点的距离和,还没有更新的距离和);如果说\(dislazy\)不下传,那么就没问题(因为就说明第\(k-1\)次操作之后的最新的\(dis\)的值就是我们之前使用的那个\(dis\)),如果说\(dislazy\)要下传,那么现在\(dis\)就要变化,减少\(dislazy\times 子节点区间长度\),而由于前面下传了\(lazy\),说明这个区间的权值都是一样的,故\(sum=value\times dis\)(此时\(dis\)已经被更新了)

假设现在\(lazy\)不下传,如果说\(dislazy\)也不下传,那么没有问题,因为就相当于没有任何更新,否则的话,\(sum\)应该如何变化呢?此时,由于这个区间的每一个点都要减少\(dislazy\),那么每一个点对\(sum\)的贡献就会减少这个点的权值乘以\(dislazy\),所以说\(sum\)就会减少\(dislazy\times 区间权值和\)。也就是说,我们现在维护的量是不够的,我们还要多维护一个区间权值和(注意不能用区间权值代替,因为点的权值可能不完全相同)

剩下的分析就跟上面差不多了,自己分析一下,然后根据代码对照一下

值得一提的是,这里其实到底是\(lazy\)优先级更高还是\(dislazy\)优先级更高是无所谓的

update 2024.7.29

更简单的方法

所以以后不一定非要直接维护题目给出的信息,也可以先选择进行变换一下再维护

posted @ 2024-05-17 21:12  最爱丁珰  阅读(1)  评论(0编辑  收藏  举报