[数据结构] 线段树历史信息维护
Un1quAIoid · · 个人记录
感觉线段树维护历史信息的题做完就忘 /yun……于是开篇文章记录下
本文认为
主要思路
线段树的维护需要考虑三个方面
- 信息与信息合并
- 信息与标记合并
- 标记与标记合并
其中第一点就是 push_up 函数,在这类题中一般都是平凡的,不再赘述。
关键在于最后两点,将每个节点上覆盖的按时间排序的操作序列提取出来,我们的目标就是将这一段
1. 历史最值
先来一道练手题:SP2916
一道经典的区间非空最大子段和的一眼题,线段树节点维护最大前后缀以及最大子段和即可。
不过这里我想提出来另一种非空最大子段和做法:区间加,区间维护历史最大值。我才不会说我是因为脑梗没看出来维护最大子段和所以用维护历史最值方法做的
将序列做前缀和,不难发现询问
首先肯定要对每个线段树节点维护区间最值和区间历史最值两个值,然后考虑怎样描述一个节点上的操作序列,假设当前节点有操作序列:
假如我们只用序列的和来描述的话,当我们下传该序列接到儿子的序列之后时就会发现我们无法更新儿子的历史最大值了,因为实际上可能是在某一时刻
那么此时正解就十分显然了,除了维护
代码(实现上这种类型只需要改一下 push_down 即可)
习题(有题再加):
- P4314 CPU 监控 (加上了赋值操作,考虑将赋值操作后的所有加法操作变为赋值操作)
- P6242 【模板】线段树 3 (与势能线段树的结合
怎么突然难那么多啊喂) - 题真的好少QAQ
2、历史版本和
考虑加上区间累加操作
考虑用
习题(有题再加):
- P3246 [HNOI2016]序列 (好像题解区还没有历史版本和的解法,这里给出我的代码,
好像只要差分一下就可以了,我又双叒叕想麻烦了) - CF997E Good Subsegments (扫描线技巧,区间加维护最小值0历史出现次数,需要仔细观察性质)
- 这个也少QAQ
语言没有怎么仔细打磨,哪里讲得不清楚还请指出QAQ,反正未来的我能看懂就行(逃