集训总结(六)
9.15
听 CEO 讲了 sb 树,不知道该写什么,挂个祂博客的链接吧。
https://www.cnblogs.com/Augenstern-/p/18964066
9.16
考试。考的一坨。
由于是原创题,所以就不放了。
9.17
四方喝彩
本来打算把这个当考试题的,但我找到了一个更好的,所以就弃了这个。
如果没有操作三,这题就是一个线段树二板子,所以我们只需要考虑操作三的影响。
先看操作一。此时的区间加,我们不能再写 \(+(r-l+1)*k\) 了,因为我们需要考虑封锁的区间。我们额外维护一个 \(sum\) ,一个 \(len\) 和一个 \(tag\),表示封锁区间和,未封锁区间长度以及该区间是否被封锁。这样操作一就很好维护了。
操作二同理。
再看操作三,我们要解决的是如何封锁一个区间以及如何解封。
先看封锁区间,我们分类讨论:
1.如果此区间代表的节点还有子节点(也就是区间长度不为一),我们就将区间信息 \(pushdown\),然后打封锁标记。
2.如果此区间为叶子结点(区间长度为一),我们将未封锁区间的信息更新到封锁区间,然后打封锁标记。
再看解封区间,依然是分类讨论:
1.如果此区间长度不为一,我们对这个区间进行 \(pushup\) 操作,然后解封。
2.如果此区间长度为一,我们将封锁区间的信息更新到未封锁区间,然后解封。
但是这样对吗?我们发现,一个区间可能会被封锁多次,所以我们需要稍加改变。我们将前面提到的 \(tag\) 标记含义更改一下,表示该区间被封锁的次数。封锁时 \(tag+1\),解封时 \(tag-1\),判断 \(tag\) 是否为 \(0\),决定是否进行解封操作。这样我们就完成了操作三。
操作四就很简单了,直接将封锁区间和以及未封锁区间和加起来,输出就行。
注意 \(pushdown\) 和 \(pushup\) 时要先判断区间是否被封锁才能下放/上传标记。