概念

李超线段树可用来维护直线关系,支持:
1* 加入一条直线
2* 询问单点对应最优直线
结构与普通线段树类似,但更多分情况讨论

LuoguP4254 [JSOI2008]Blue Mary开公司

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a))
#define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a))
#define Fill(a,b) memset(a, b, sizeof(a))
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
#define ll long long
#define u32 unsigned int
#define u64 unsigned long long

#define ON_DEBUGG

#ifdef ON_DEBUGG

#define D_e_Line printf("\n----------\n")
#define D_e(x) cout << (#x) << " : " << x << endl
#define Pause() system("pause")
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#include <ctime>
#define TIME() fprintf(stderr, "\ntime: %.3fms\n", clock() * 1000.0 / CLOCKS_PER_SEC)

#else

#define D_e_Line ;
#define D_e(x) ;
#define Pause() ;
#define FileOpen() ;
#define FileSave() ;
#define TIME() ;
//char buf[1 << 21], *p1 = buf, *p2 = buf;
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)

#endif

using namespace std;
struct ios{
    template<typename ATP>inline ios& operator >> (ATP &x){
        x = 0; int f = 1; char ch;
        for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
        while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
        x *= f;
        return *this;
    }
}io;

template<typename ATP>inline ATP Max(ATP a, ATP b){
    return a > b ? a : b;
}
template<typename ATP>inline ATP Min(ATP a, ATP b){
    return a < b ? a : b;
}
template<typename ATP>inline ATP Abs(ATP a){
    return a < 0 ? -a : a;
}

const int N = 5e5 + 7;
const int M = 5e5 + 3;

int tot;

double K[N << 1], B[N << 1];

int t[N << 2] ;
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
// y = k * x + b

double Calc(int id, int x) {
    return K[id] * (x - 1) + B[id];
}

inline void Updata(int rt, int l, int r, int x) {
    if(l == r){
        if(Calc(x, l) > Calc(t[rt], l)) t[rt] = x;
        return;
    }
    int mid = (l + r) >> 1;
    if(K[t[rt]] < K[x]){
        if(Calc(x, mid) > Calc(t[rt], mid)){
            Updata(lson, t[rt]);
            t[rt] = x;
        }
        else{
            Updata(rson, x);
        }
    }
    if(K[t[rt]] > K[x]){
        if(Calc(x, mid) > Calc(t[rt], mid)){
            Updata(rson, t[rt]);
            t[rt] = x;
        }
        else{
            Updata(lson, x);
        }
    }
}

inline double Query(int rt, int l, int r, int x) {
    if(l == r) return Calc(t[rt], x);
    int mid = (l + r) >> 1;
    if(x <= mid){
        return Max(Calc(t[rt],x), Query(lson, x));
    }
    else{
        return Max(Calc(t[rt], x), Query(rson, x));
    }

}
int main() {
    int n;
    io >> n;
    char opt[13];
    while(n--){
        scanf("%s", opt + 1);
        if(opt[1] == 'P'){
            ++tot;
            scanf("%lf%lf", &B[tot], &K[tot]);
            Updata(1, 1, M, tot);
        }
        else{
            int x;
            io >> x;
            printf("%d\n", (int)Query(1, 1, M, x) / 100);
        }
    }

    return 0;
}
01-16 20:15
查看更多