【luogu P4254】Blue Mary开公司(李超线段树)

Blue Mary开公司

题目链接:luogu P4254

题目大意

要你支持两个操作。
加入一条线段,或者查询在某一个 x 坐标上哪一条线段对于的 y 值最大,输出这个最大的 y。

思路

这道题其实就是李超线段树板子题

甚至还简单了?

注意你第一天是 b b b,第二天是 k + b k+b k+b,第 x x x 天使 ( x − 1 ) k + b (x-1)k+b (x1)k+b

代码

#include<cstdio>
#include<iostream>

using namespace std;

int q, x, n;
char s[101];
double k[1000001], b[1000001];

double f(int id, int x) {
	return k[id] * (x - 1) + b[id];
}

struct XDTree {
	int s[500001 << 2];
	
	void up(int now, int l, int r, int x) {
		if (l == r) {
			if (f(x, l) > f(s[now], l)) {
				s[now] = x;
			}
			return ;
		}
		
		int mid = (l + r) >> 1;
		if (k[x] > k[s[now]]) {
			if (f(x, mid) > f(s[now], mid)) up(now << 1, l, mid, s[now]), s[now] = x;
				else up(now << 1 | 1, mid + 1, r, x);
		}
		else {
			if (f(x, mid) > f(s[now], mid)) up(now << 1 | 1, mid + 1, r, s[now]), s[now] = x;
				else up(now << 1, l, mid, x);
		}
	}
	
	double query(int now, int l, int r, int x) {
		if (l == r) return f(s[now], x);
		
		int mid = (l + r) >> 1;
		if (x <= mid) return max(f(s[now], x), query(now << 1, l, mid, x));
			else return max(f(s[now], x), query(now << 1 | 1, mid + 1, r, x));
	}
}T;

int main() {
	scanf("%d", &q);
	while (q--) {
		scanf("%s", s + 1);
		if (s[1] == 'Q') {
			scanf("%d", &x);
			printf("%d\n", (int)(T.query(1, 1, 50000, x) / 100));
		}
		else {
			n++;
			scanf("%lf %lf", &b[n], &k[n]);
			T.up(1, 1, 50000, n);
		}
	}
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值