【模板】李超线段树 / [HEOI2013] Segment
李超线段树是一种用于维护平面直角坐标系内线段关系的数据结构,插入直线/线段,支持查询单点极值(指的是某一个横坐标,所有直线的对应函数值的最大/小值)
李超树的经典应用是斜率优化,可以看下这篇文章
以下叙述基于洛谷模板题
李超线段树没有用懒标记实现区间修改,而用的是标记永久化
其实标记永久化与我们对lazy标记的理解非常相同,可以看看LYD蓝书上对标记永久化的解释,都是累积某个节点到根节点路径上的所有点的影响
具体来说,我们用
任意一个时刻,线段树上的任意一个节点的
那么我们怎么修改呢?标记永久化是不用下传的,想一下,如果一个节点没有被
所以我们只用一直递归,直到某个节点被修改区间完全包含为止
此时,我们怎么修改呢?
如果这个区间还没有线段,那么直接令这个区间的
如果这个区间已经有一个线段了,比如
其中
就如我们图像所看到的,我们很明显的应该保存形状为“V”的折线段(实际中的线段树上的点是离散的,这个不影响),所以左子节点就可以直接赋值,然后右子节点往下递归修改就好了
具体来说,设当前区间的中点为
如果新线段
-
若在左端点处
更优,那么 和 必然在左半区间中产生了交点, 只有在左区间才可能优于 ,递归到左儿子中进行下传; -
若在右端点处
更优,那么 和 必然在右半区间中产生了交点, 只有在右区间才可能优于 ,递归到右儿子中进行下传; -
若在左右端点处
都更优,那么 不可能成为答案,不需要继续下传。 -
和 刚好交于中点,在程序实现时可以归入中点处 不如 优的情况,结果会往 更优的一个端点进行递归下传。
最后令
参考代码:
void modify(int p,int l,int r,int x,int y,int u)
{
if(l>y||r<x) return;
if(x<=l&&y>=r)
{
update(p,l,r,u);
return;
}
int mid=l+r>>1;
//标记永久化不下放标记
//直接递归
modify(p<<1,l,mid,x,y,u);
modify(p<<1|1,mid+1,r,x,y,u);
}
double calc(int id,int d)
{
return q[id].b+q[id].k*d;
}
int cmp(double x, double y)
{
if(x-y>eps) return 1;
if(y-x>eps) return -1;
return 0;
}
void update(int p,int l,int r,int u)
{
int &v=s[p],mid=l+r>>1;
int bmid=cmp(calc(u,mid),calc(v,mid));//判断f和g的中点值大小
if(bmid==1||(!bmid&&u<v)) swap(u,v);
//这里如果中点相等
//我们交换反正不会遗漏纵坐标的最优值
//而且还可能使得编号更优
//就是白换白不换
//其实这里可以不换,因为编号更小的仍然会被保留,后面统计答案的时候不会漏掉
int bl=cmp(calc(u,l),calc(v,l)),br=cmp(calc(u,r),calc(v,r));
if(bl==1||(!bl&&u<v)) update(p<<1,l,mid, u);
if(br==1||(!br&&u<v)) update(p<<1|1,mid+1,r,u);
//其实这两个判断||后面的这个判断条件是需要的
//在端点处有可能会因为编号更优而更新
//但也可能导致一个问题
//如果修改的这条线段与原来的某个线段完全重合
//上面两个update就会同时递归
//复杂度就会退化了
}
不难看出时间复杂度是
那么为什么最开始交换
查询参考代码:
pdi pmax(pdi x,pdi y)
{
if(cmp(x.first,y.first)==-1)
return y;
else if(cmp(x.first,y.first)==1)
return x;
else//如果纵坐标相同,返回编号更小的一个点
return x.second<y.second?x:y;
}
pdi ask(int p,int l,int r,int d)
{
if(r<d||l>d) return {0,0};
int mid=l+r>>1;
double res=calc(s[p],d);
if(l==r) return {res,s[p]};
//根据标记永久化思想
//我们要累计回根路径上所有点的影响
return pmax({res,s[p]},pmax(ask(p<<1,l,mid,d),ask(p<<1|1,mid+1,r,d)));
}
注意是标记永久化
完整代码见洛谷
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY