嘟嘟嘟
題意:1.在直角座標系中加入一條直線。2.求橫座標爲\(x\)時最大的函數值。
而後有一個叫李超線段樹的東西專門解決這樣一類問題。
很巧妙,也很簡單。
我就直接給幾個連接吧。
[JSOI2008]Blue Mary開公司(李超線段樹)
李超線段樹
第二篇博客複雜度寫錯了,修改查詢都應該是\(O(logn)\)的。
個人理解就是當前區間只存暴露最多的直線,而剩下的可能成爲最優解的直線會在遞歸子區間的時候查到。html
#include<cstdio> #include<iostream> #include<cmath> #include<cstring> #include<algorithm> #include<cstdlib> #include<cctype> #include<map> #include<queue> #include<vector> #include<assert.h> using namespace std; #define enter puts("") #define space putchar(' ') #define Mem(a, x) memset(a, x, sizeof(a)) #define In inline typedef long long ll; typedef double db; const int INF = 0x3f3f3f3f; const db eps = 1e-8; const int maxt = 5e5 + 5; In ll read() { ll ans = 0; char ch = getchar(), las = ' '; while(!isdigit(ch)) las = ch, ch = getchar(); while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar(); if(las == '-') ans = -ans; return ans; } In void write(ll x) { if(x < 0) putchar('-'), x = -x; if(x >= 10) write(x / 10); putchar(x % 10 + '0'); } In void MYFILE() { #ifndef mrclr freopen("ha.in", "r", stdin); freopen("ha.out", "w", stdout); #endif } int n; char s[20]; struct Line { db b, k; friend In db Y(Line a, int x) {return a.k * (x - 1) + a.b;} }t[maxt << 2]; int l[maxt << 2], r[maxt << 2]; In void build(int L, int R, int now) { l[now] = L, r[now] = R; t[now] = (Line){0, 0}; if(L == R) return; int mid = (L + R) >> 1; build(L, mid, now << 1), build(mid + 1, R, now << 1 | 1); } In void update(int L, int R, int now, Line c) { if(L == R) { if(Y(c, L) > Y(t[now], L)) t[now] = c; return; } int mid = (L + R) >> 1; db y1 = Y(t[now], mid), y2 = Y(c, mid); if(c.k > t[now].k) { if(y2 > y1) update(L, mid, now << 1, t[now]), t[now] = c; else update(mid + 1, R, now << 1 | 1, c); } else { if(y1 > y2) update(L, mid, now << 1, c); else update(mid + 1, R, now << 1 | 1, t[now]), t[now] = c; } } In db query(int id, int now) { if(l[now] == r[now]) return Y(t[now], l[now]); int mid = (l[now] + r[now]) >> 1; db ret = Y(t[now], id); if(id <= mid) ret = max(ret, query(id, now << 1)); else ret = max(ret, query(id, now << 1 | 1)); return ret; } int main() { // MYFILE(); n = read(); build(1, maxt - 1, 1); for(int i = 1; i <= n; ++i) { scanf("%s", s); if(s[0] == 'P') { db b, k; scanf("%lf%lf", &b, &k); update(1, maxt - 1, 1, (Line){b, k}); } else write(query(read(), 1) / 100), enter; } return 0; }