总结-李超线段树

匿名 (未验证) 提交于 2019-12-03 00:14:01

李超线段树可用来维护直线关系,支持:

  • 加入一条直线
  • 询问单点对应最优直线

结构与普通线段树类似,但更多分情况讨论

模板

#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; }

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!