zoukankan      html  css  js  c++  java
  • 李超线段树学习笔记

    李超线段树支持这样的操作:

    1. 插入一条直线。
    2. 询问与$x=x_0$相交的点的最大/小的纵坐标(接下来我们以最大值为例)

    它基于线段树的标记永久化,也就是说,我们对于区间$[l,r]$维护$x=mid$上最高的直线的编号(但是如果$[l,r]$的所有点都以$[l,r]$的父亲记录的直线作为最大值,那么$[l,r]$的子树都没有记录的直线(这就是标记永久化)),然后询问操作肯定没有问题,重点就是添加直线了。

    假设当前递归到$[l,r]$,要插入$k_1x+b_1$,之前记录的直线为$k_2x+b_2$。

    不妨设$k_1<k_2$,$k_1geq k_2$的情况同理。

    第一种情况:$k_1mid+b_1>k_2mid+b_2$,那么更新$[l,r]$的标记,只向$[mid+1,r]$递归,因为$[l,mid]$上所有点都以$k_1x+b_1$作为最大值。

    第二种情况:$k_1mid+b_1leq k_2mid+b_2$,那么不更新$[l,r]$的标记,只向$[l,mid]$递归,因为$[mid+1,r]$上所有点都以$k_2x+b_2$作为最大值。

    这样显然更新一次是$O(log^2 n)$的。(我也不知道我在想什么。。。)

    #include<bits/stdc++.h>
    #define Rint register int
    using namespace std;
    const int N = 100003, M = 50000;
    int n, tot;
    struct Line {
        double k, b;
        inline double val(int x){return k * (x - 1) + b;}
    } l[N];
    int tag[M << 2];
    inline double query(int x, int L, int R, int pos){
        if(L == R) return l[tag[x]].val(L);
        int mid = L + R >> 1;
        double ans = l[tag[x]].val(pos);
        if(pos <= mid) ans = max(ans, query(x << 1, L, mid, pos));
        else ans = max(ans, query(x << 1 | 1, mid + 1, R, pos));
        return ans;
    }
    inline void insert(int x, int L, int R, int id){
        if(L == R){
            if(l[tag[x]].val(L) < l[id].val(L)) tag[x] = id;
            return;
        }
        int mid = L + R >> 1;
        if(l[tag[x]].k < l[id].k){
            if(l[tag[x]].val(mid) < l[id].val(mid)){insert(x << 1, L, mid, tag[x]); tag[x] = id;}
            else insert(x << 1 | 1, mid + 1, R, id);
        } else {
            if(l[tag[x]].val(mid) < l[id].val(mid)){insert(x << 1 | 1, mid + 1, R, tag[x]); tag[x] = id;}
            else insert(x << 1, L, mid, id);
        }
    }
    int main(){
        scanf("%d", &n);
        while(n --){
            char s[10]; scanf("%s", s);
            if(s[0] == 'Q'){
                int t;
                scanf("%d", &t);
                printf("%d
    ", (int) query(1, 1, M, t) / 100);
            } else {
                ++ tot;
                scanf("%lf%lf", &l[tot].b, &l[tot].k);
                insert(1, 1, M, tot);
            }
        }
    }
    Luogu4254

    例题:CF1175G(如果认为难度落差太大,本人不负责)

  • 相关阅读:
    非监督学习
    4.5_岭回归案例分析
    4.4_回归算法之岭回归
    4.3_回归性能评估与欠拟合|过拟合
    4.2_线性回归案例分析
    回归算法
    HDU 2105 The Center of Gravity (数学)
    HDU 2089 不要62 (数学)
    HDU 2036 改革春风吹满地 (数学)
    HDU 1840 Equations (数学)
  • 原文地址:https://www.cnblogs.com/AThousandMoons/p/11040257.html
Copyright © 2011-2022 走看看