标签:img names opened 最大 scanf pac 一次函数 维护 模版题
题意:插入一些一次函数线段 每次询问在x = x0处这些线段的最大值
题解:李超树模版题 维护优势线段
注意这题的输入是x=1时的b
#include <iostream> #include <stdio.h> using namespace std; const int MAXT = 50000; #define pff pair<double, double> int tot, rt; char s[50]; pff t[MAXT << 5]; int ls[MAXT << 5], rs[MAXT << 5]; double ans; double fun(pff x, int y) { return x.first * (1.0 * (y - 1)) + x.second; } void add(int &k, int l, int r, pff x) { if(!k) { k = ++tot; t[k] = x; return; } int mid = l + r >> 1; if(fun(t[k], l) < fun(x, l) && fun(t[k], r) < fun(x, r)) { t[k] = x; return; } if(fun(t[k], l) > fun(x, l) && fun(t[k], r) > fun(x, r)) return; if(t[k].first < x.first) { if(fun(t[k], mid) < fun(x, mid)) add(ls[k], l, mid, t[k]), t[k] = x; else add(rs[k], mid + 1, r, x); } else { if(fun(t[k], mid) > fun(x, mid)) add(ls[k], l, mid, x); else add(rs[k], mid + 1, r, t[k]), t[k] = x; } /* if(fun(x, mid) > fun(t[k], mid)) swap(t[k], x); if(fun(x, l) > fun(t[k], l)) add(ls[k], l, mid, x); if(fun(x, r) > fun(t[k], r)) add(rs[k], mid + 1, r, x); */ } double ask(int k, int l, int r, int x) { //if(!k) return -(1.0 * (1 << 30)); if(l == r) return fun(t[k], x); int mid = l + r >> 1; double res = fun(t[k], x); if(x <= mid) return max(res, ask(ls[k], l, mid, x)); else return max(res, ask(rs[k], mid + 1, r, x)); } int main() { int T; cin>>T; while(T--) { scanf("%s", s + 1); if(s[1] == ‘P‘) { double x, y; scanf("%lf%lf", &x, &y); add(rt, 1, MAXT, pff(y, x)); } else { int x; scanf("%d", &x); printf("%d\n", (int)(ask(rt, 1, MAXT, x) / 100.0)); } } return 0; }
P4254 [JSOI2008]Blue Mary开公司 (李超树)
标签:img names opened 最大 scanf pac 一次函数 维护 模版题
原文地址:https://www.cnblogs.com/lwqq3/p/12357896.html