李超线段树

李超线段树

李超线段树是线段树的一个变种,主要支持在平面直角坐标系中动态地插入线段或直线,并查询某一条平行于 y 轴的直线与所有直线或线段的交点的纵坐标的最值。


假设只插入直线并且维护最大值:

在李超线段树中,对于每一个结点,我们需要维护的是在这个结点所对应的区间 [l,r] 的中点处取值最大的直线。

假设我们现在有两条直线 y1=3x+5,y2=2x+6,当前结点对应的区间为 [1,4]

那么,我们就比较这两条直线在 x=2 时的取值:

图中绿色直线是直线 y=3x+5,蓝色直线是 y=2x+6,很显然的,当 x=2 时,直线 y=3x+5 更优。

因此,区间 [1,4] 所对应的直线就是 y=3x+5

那么 y=2x+6 应该怎么办呢?

这时,我们考虑比较这两条直线的斜率,我们会发现 y=2x+6 的斜率更小一些,也就是意味着,当 x>2 时,直线 y=3x+5 的取值一定比 y=2x+6 更大,因此,我们只会用这条直线更新左区间。

但是需要注意的是当两条直线斜率相同时,就可以直接退出了。


有时候为了防止一些小数的情况,李超线段树通常我会写成左闭右开的形式。

并且由于坐标的范围问题,通常我会写动态开点。

ll F(Node x, int pos) {
    return 1ll * x.k * pos + x.b;
}

void add(Node x) {
    int i = 1, l = -INF, r = INF + 1;
    while (l + 1 <= r) {
        if (tr[i].b == inf) {
            tr[i] = x; break;
        }

        int mid = l + (r - l) / 2;

        if (F(tr[i], mid) > F(x, mid)) swap(tr[i], x);
        if (l + 1 == r || tr[i].k == x.k) break;

        if (tr[i].k > x.k) {
            if (!son[i][1]) son[i][1] = ++c, tr[c] = {0, inf};
            i = son[i][1], l = mid;
        } else {
            if (!son[i][0]) son[i][0] = ++c, tr[c] = {0, inf};
            i = son[i][0], r = mid;
        }
    }
}

ll query(int x) {
    int i = 1, l = -INF, r = INF + 1;
    ll tp = inf;
    while (l + 1 <= r && i) {
        int mid = l + (r - l) / 2;

        tp = min(tp, F(tr[i], x));

        if (l + 1 == r) break;

        if (x < mid) i = son[i][0], r = mid;
        else i = son[i][1], l = mid;
    }
    return tp;
}

而如果是插入线段的话,事实上就是先找到线段所覆盖的区间,然后和直线一样更新线段树上的直线即可。

这里最需要注意的就是左闭右开区间的边界判断问题。

void modify(int i, int l, int r, int ql, int qr, Node x) {
    if (qr <= l || ql >= r) return ;
    if (ql <= l && r <= qr) {
        add(x, i, l, r);
        return ;
    }
    if (l + 1 == r) return ;
    int mid = l + (r - l) / 2;

    if (!son[i][0]) son[i][0] = ++c, tr[c] = {0, inf};
    modify(son[i][0], l, mid, ql, qr, x);

    if (!son[i][1]) son[i][1] = ++c, tr[c] = {0, inf};
    modify(son[i][1], mid, r, ql, qr, x);
}

作者:cn

出处:https://www.cnblogs.com/chengning0909/p/18401219

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   chengning0909  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up light_mode palette
选择主题
点击右上角即可分享
微信分享提示