【模板】李超线段树 / [HEOI2013] Segment

发布时间 2023-12-29 00:07:22作者: 最爱丁珰

李超线段树是一种用于维护平面直角坐标系内线段关系的数据结构,插入直线/线段,支持查询单点极值

李超树的经典应用是斜率优化,可以看下这篇文章

李超线段树没有用懒标记实现区间修改,而用的是标记永久化

其实标记永久化与我们对lazy标记的理解非常相同,可以看看LYD蓝书上对标记永久化的解释,都是累积某个节点到根节点路径上的所有点的影响

具体来说,我们用\(s[p]\)表示线段树上\(p\)节点存储线段的编号,每次的修改的区间就是\([x_0,x_1]\)

任意一个时刻,线段树上的任意一个节点的\(s[p]\)的值是唯一的,对于一个叶子节点,他的真实线段编号(假设这个叶子节点的横坐标是\(x_0\),我们做一条直线\(x=x_0\),与所有已经插入的线段的交点纵坐标最大且在此前提下线段标号最小的线段的编号)就是从这个叶子节点到根节点的路径上所有节点存储的线段进行计算比较得出来的那一条线段

那么我们怎么修改呢?标记永久化是不用下传的,想一下,如果一个节点没有被\([x_0,x_1]\)完全包含,只是相交,那么我们不动这个节点的\(s[p]\),对最终的答案是没有影响的,任意一个叶子节点往上走所得到的真实线段一定是不会被遗漏的

所以我们只用一直递归,直到某个节点被修改区间完全包含为止

此时,我们怎么修改呢?

如果这个区间还没有线段,那么直接令这个区间的\(s[p]\)为当前这个修改区间的编号并且返回即可

如果这个区间已经有一个线段了,比如

其中\(f\)是新插入的线段,\(g\)是原来的线段

就如我们图像所看到的,我们很明显的应该保存形状为“V”的折线段(实际中的线段树上的点是离散的,这个不影响)