2025-02-15线段树(区间修改)
线段树(区间修改)
主要内容
区间修改与懒标记
线段树是一种高效的数据结构,用于处理区间查询和修改操作。当涉及到区间修改时,懒标记(Lazy Propagation)是一种重要的优化手段,可以避免每次修改都直接更新所有节点,从而提高效率。懒标记的基本思想是将修改操作延迟到必要时才进行。
以下是懒标记的实现要点:
- 标记存储:在每个节点中存储懒标记,表示当前节点的区间需要进行的修改操作。
- 标记下推:在访问子节点之前,将当前节点的懒标记下推到子节点。
- 标记清除:在将懒标记下推后,清除当前节点的懒标记。
- 标记累积:如果当前节点已经有懒标记,新的修改操作需要与旧的懒标记进行累积。
扫描线算法
扫描线算法是一种用于处理几何问题(如矩形面积并、线段覆盖等)的算法。其基本思想是将问题分解为一系列事件(如线段的起点和终点),并按照某种顺序(通常是横坐标)处理这些事件。
以下是扫描线算法的实现要点:
- 事件排序:将所有事件按照横坐标排序。
- 线段树维护:使用线段树维护当前扫描线的覆盖状态。
- 离散化:对于浮点数坐标,需要进行离散化处理。
- 动态更新:在扫描过程中,动态更新线段树的状态,并计算结果。
注意:
- 扫描线 算法解决覆盖区间求并的问题
- 以x轴作为扫描的方向(要将线段按x大小排序),我们要计算的是扫过的面积,所以
不包含第一条线
- 线段树的
端点
是y方向上的区间
(因为要维护长度!), 映射tr[i].l ... tr[i].r
对应ys[tr[i].l-1] ... ys[tr[i].r-1+1]
- 由于y值可能为浮点数,所以需要离散化
- 要维护的属性有
cnt
,入边+1
, 出边-1
;还有len
,保存的是区间内的覆盖长度
- 这里虽然要对区间进行修改,但是我们每次查询只针对
根节点
,即tr[1]
,所以只要在modify及时pushup,就不需要pushdown操作 - 扫描线虽然用到了线段树,但比较反常,所以背过是最好的方式-_-||
多个懒标记的累积
当线段树中存在多个懒标记时,需要正确处理它们的累积。例如,在区间加法和乘法的组合操作中,需要先处理乘法标记,再处理加法标记。累积公式如下:
- 乘法标记累积:
mul_new = mul * mul'
- 加法标记累积:
add_new = add * mul' + add'
例题
一个简单的整数问题2
1 |
|
亚特兰蒂斯
1 |
|
维护序列
1 |
|
2025-02-15线段树(区间修改)
http://666xz666.github.io/2025/02/15/线段树(区间修改)/