【学习笔记】李超线段树
李超线段树
动态维护一个平面直角坐标系,支持在中间插入一条线段,支持询问与 这条直线相交的所有线段中,交点的 轴坐标的最大(小)值。
想到把一条线段拆成 值为整数的点,这里 值开 就没有问题了
主要是考虑怎么插入一条直线,假设它当前处理到了某个区间:
-
区间没有记录最长的线段:那么直接把这个区间记录的线段修改为这条线段
-
当前线段在这个区间内已经被这个区间内的最长线段为覆盖: 直接返回。
-
完全覆盖了之前记录的线段: 区间修改
-
和已经记录的直线有交:判断哪根线段覆盖的区域较长,把这个区间记录的值给修改一下,然后把短的那一半丢下去递归。
查询还是很水的
Code Part
inline void insert(int p,int l,int r,int x1,int x2,node now)
{
if(l>=x1&&r<=x2)
{
int mid=(l+r)>>1;
if(calc(t[p],mid)<calc(now,mid)||(!t[p].num)) swap(t[p],now);
double jd=1.0*(t[p].b-now.b)/(now.k-t[p].k);
if(l==r||t[p].k==now.k||jd<1.0*l||jd>1.0*r||(!now.num)) return ;
if(now.k<t[p].k) insert(p<<1,l,mid,x1,x2,now);
else insert(p<<1|1,mid+1,r,x1,x2,now);
}
else
{
int mid=(l+r)>>1;
if(x1<=mid) insert(p<<1,l,mid,x1,x2,now);
if(x2>mid) insert(p<<1|1,mid+1,r,x1,x2,now);
}return ;
}
inline node query(int p,int l,int r,int x)
{
if(l==r) return t[p];
int mid=(l+r)>>1; node k;
if(x<=mid) k=query(p<<1,l,mid,x);
else k=query(p<<1|1,mid+1,r,x);
return ((!k.num)||calc(k,x)<calc(t[p],x))?t[p]:k;
}
例题
HEOI2013 Segment
确实是模板题,甚至上面的码就是粘的那里的
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律