李超线段树可用来维护直线关系,支持:
- 加入一条直线
- 询问单点对应最优直线
结构与普通线段树类似,但更多分情况讨论
模板
#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; }
来源:博客园
作者:邱涵的秘密基地
链接:https://www.cnblogs.com/bingoyes/p/11655123.html