线段树题单
Problem 1
P4588 [TJOI2018]数学计算(没区间没数列没树但是要用线段树...)
维护线段树,支持区间求积,单点修改即可。水题不讲。
Problem 2
发现一个的数开6次根一定是1,然后无论开多少次根都不变了。可以维护一个最大值的线段树,如果区间内全是1就不管,否则暴力遍历开方。(在最大值线段树上找非1数是不行的,最坏)
然后一个个直接更新不需要lazytag,最坏,但是完全是的操作最多出现6次,可以通过。
水蓝水蓝
Problem 3
请不要使用的暴力,这会让这道下位紫题变成思维绿。
Part 1
很显然,我们需要快速地查询两个组合是否相等,还需要自由地在组合间移动人。
我们可以使用hash. 给每个人一个随机生成的tag,而组合的hash值就是所有成员的tag异或起来。增加/减少成员时,把组合的hash值异或上移动了的成员的tag即可。
我们把已经做过实验的组合的hash扔到set里,查询有没有做过实验时直接s.find(hash)==s.end()?true:false
。
Part 2
做一个资瓷单点修改,区间ban(被ban的房间人数变为0),单点复原,区间求和的线段树。
只有一个bool型的lazytag,表示当前区间有没有被全ban.
区间求和计算方法和普通的不一样,即使当前区间完全被查询区间覆盖,如果没有全ban,也要往深层继续查询。
单点修改正常修改,但是修改以后被ban的情况可能会发生改变,新写一个update函数,一路从根节点pushdown下去,最后改一下单点(叶子结点)的lazytag即可。
被ban的区间内的房间的hash并不需要立刻存入set内,在pushdown到叶子结点的时候存就可以了。原因自己想。(hint:所有成员都是唯一的)
Part 3
一些废话:
-
随机函数最好自己写,不难。
-
成员换房间的时候先更新人数,再update两个房间的lazytag(这时先不改那两个房间的实际hash值),然后最后再改hash值。原因自己想。(hint:pushdown会存hash
这已经不是hint而是最终答案了() -
成员可能会“从原来的房间到原来的房间”,就是完全没动。这种情况一定要特判然后忽略,不然hash会出大问题。
Problem 4
P2572 [SCOI2010] 序列操作(线段树操作大杂烩了属于是)
题目相当于要维护一个01线段树,支持区间推平,区间取反,区间求和,区间最长连续1.
我们一个一个来看。
维护数据
区间推平
维护两个lazytag,和,分别表示把当前区间推平成。
区间取反
再维护一个lazytag ,表示取反当前区间。
区间求和
维护一个数据,表示当前区间的个数(等价于区间和)。
区间最长连续1
和GSS3相似,维护三个东西:区间左边最长连续1,区间右边最长连续1,区间最长连续1. 分别用表示。
Extra
在实际情况中,还要维护区间左边最长连续0,区间右边最长连续0,区间最长连续0. 分别用表示。具体作用后面会说。
所以我们的线段树有以下的东西:
结构:(区间和子树,线段树必需)
lazytag:
数据:
数据间影响
lazytag之间
lazytag之间的优先级不像线段树2一样,比较好维护,所以可以让每一个节点保证同时只有一个lazytag。
把“从祖先push_down下来的lazytag”叫做下传标记,“原有的lazytag”叫做原有标记。
下传标记是时,清空所有原有标记再下传(清空不是指进一步下传标记而是直接覆盖掉)。显然,不管前面积压了多少操作,推平以后都全是,所以前面积压的lazytag已经无意义.
下传标记是时同理,清空所有原有标记再下传.
下传标记是时,如果原有,那么直接把变成,或把变成即可(相当于交换两个标记)。这时下传下来的rev直接清空。
如果没有,就直接把原有异或一下。(反转再反转相当于没动,所以是异或而不是直接改成true.)
lazytag和数据之间
消除当前点的lazytag(也就是push_down)时,各数据也需要相应变化。
设位区间长度。
消除时,清零,改成,清零。显然。
消除时,改成,清零,改成。
消除时,变成(01互换), 互换。(这也是为什么需要额外计算),否则反转的时候没法维护了。
数据的计算
各数据从下往上更新的方法。
:两儿子的和。
:如果左儿子区间全是0,那么答案就是左右儿子的和;否则仅为左儿子的的值。
:同理。
:如果右儿子区间全是0,那么答案就是左右儿子的和;否则仅为右儿子的的值。
:同理。
:左右儿子的,左儿子的+右儿子的这三个值取max。
:同理。
Extra
在区间连续1查询中,方式和计算cont1相似而不同。需要考虑有可能当前区间内的连续1并不完全在查询的区间内,需要分别算出左右端点进行处理。
经过了以上繁琐的操作,我们就容易得到下面的代码了。
能够完全理解并写出来这道题(并且debug完)证明线段树的各种操作基本上掌握的很透彻了。
p.s. 这题debug真的很搞人心态。
---------------------------------这是一片分界线---------------------------------
Problem 5
P3384 【模板】重链剖分/树链剖分(树剖也用了线段树...好像没毛病哈
看情况讲不讲罢。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】