『李超线段树』洛谷P4254 [JSOI2008]Blue Mary开公司

博客介绍了如何使用李超线段树解决Blue Mary开公司时,根据金融顾问的经营方案估算某天最大收益的问题。通过分析线段树的延迟标记和优势线段,讲解了插入新线段和区间查询的处理方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

『题意描述』


Blue Mary 最近在筹备开一家自己的网络公司。由于他缺乏经济头脑,所以先后聘请了若干个金融顾问为他设计经营方案。

万事开头难,经营公司更是如此。开始的收益往往是很低的,不过随着时间的增长会慢慢变好。也就是说,对于一个金融顾问 i,他设计的经营方案中,每天的收益都比前一天高,并且均增长一个相同的量 P_i。

由于金融顾问的工作效率不高,所以在特定的时间,Blue Mary 只能根据他已经得到的经营方案来估算某一时间的最大收益。由于 Blue Mary 是很没有经济头脑的,所以他在估算每天的最佳获益时完全不会考虑之前的情况,而是直接从所有金融顾问的方案中选择一个在当天获益最大的方案的当天的获益值,例如:

有如下两个金融顾问分别对前四天的收益方案做了设计:

  第一天 第二天 第三天 第四天 P_i
顾问 1 1 5 9 13 4
顾问 2 2 5 8 11 3

在第一天,Blue Mary认为最大收益是 2(使用顾问 2 的方案),而在第三天和第四天,他认为最大收益分别是 9 和 13(使用顾问 1 的方案)。而他认为前四天的最大收益是:

2 + 5 + 9 + 13 = 292+5+9+13=29

现在你作为 Blue Mary 公司的副总经理,会不时收到金融顾问的设计方案,也需要随时回答 Blue Mary 对某天的“最大收益”的询问(这里的“最大收益”是按照 Blue Mary 的计算方法)。一开始没有收到任何方案时,你可以认为每天的最大收益值是 0。下面是一组收到方案和回答询问的例子:

询问 2
回答 0
收到方案:0 1 2 3 4 5 ……
询问 2
回答 1
收到方案:2 2.1 2.2 2.3 2.4 ……
询问 2
回答 2.1

【输入格式】:

第一行 :一个整数 NN ,表示方案和询问的总数。

接下来 NN 行,每行开头一个单词QueryProject

若单词为Query,则后接一个整数 T,表示 Blue Mary 询问第 T 天的最大收益。

若单词为Project,则后接两个实数 S,P,表示该种设计方案第一天的收益 S,以及以后每天比上一天多出的收益 P。

【输出格式】:

对于每一个Query,输出一个整数,表示询问的答案,并精确到整百元(以百元为单位,例如:该天最大收益为 210 或 290 时,均应该输出 2)。没有方案时回答询问要输出 0。

【输入样例#1】:

### 李超线段树算法实现与应用 #### 什么是李超线段树李超线段树是一种特殊的线段树,主要用于解决动态插入直线并查询某一点 \(x = k\) 的情况下,这些直线所对应的 \(y\) 值的最大值或最小值问题[^1]。 #### 数据结构设计 为了高效处理这类问题,李超线段树通过维护每一段区间内的最优直线集合来减少冗余计算。具体来说,在每个节点中存储一条代表当前区间的最佳直线(即对于该区间中的任意 \(x\) 都能给出最大/最小的 \(y\))。当新直线被加入时,会根据其斜率和截距判断是否需要替换现有直线或者进一步细分区间[^2]。 #### 时间复杂度分析 由于每次新增加一条直线最多只会分裂两个子区间,并且整个过程类似于平衡二叉查找树的操作模式,因此单次更新操作的时间复杂度为 O(log n),其中n表示叶子结点数量或者说定义域范围大小。同样地,因为只需要沿着路径访问少数几个节点即可完成询问,所以查询操作也达到了同样的效率级别O(log n)[^3]。 以下是基于Python语言的一个简单版本实现: ```python class LiChaoTree: INF = float('inf') def __init__(self, xmin=-int(1e9), xmax=int(1e9)): self.xmin = xmin self.xmax = xmax self.tree = {} def f(self, line_id, x): a, b = lines[line_id] return a * x + b def add_line(self, id_new): def update(node, l, r): if node not in self.tree or (l != r and self.f(id_new, (l+r)//2) < self.f(self.tree[node], (l+r)//2)): tmp = self.tree.get(node, None) self.tree[node] = id_new if l != r: mid = (l + r) // 2 if self.f(tmp, l) < self.f(id_new, l): update(2*node+1, l, mid) else: update(2*node+2, mid+1, r) update(0, self.xmin, self.xmax) def query_min(self, x): res = LiChaoTree.INF pos = 0 while True: if pos in self.tree: res = min(res, self.f(self.tree[pos], x)) if pos >= len(self.tree)-1 or self.xmin == self.xmax: break mid = (self.xmin+self.xmax)//2 if x <= mid: pos = 2*pos+1 self.xmax = mid else: pos = 2*pos+2 self.xmin = mid+1 return res ``` 此代码片段展示了如何构建一个基本框架用于管理一系列函数\(f(x)=ax+b\). 它允许我们有效地添加新的线条以及找到给定位置上的最低可能结果. #### 应用场景举例 - **几何最优化**: 如寻找覆盖特定区域的最佳传感器布置方案. - **经济模型预测**: 对未来收益曲线进行实时调整的同时保持快速检索能力. - **游戏AI发**: 计算单位移动成本地图上两点间最快路线等问题也可能涉及此类技术的应用.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值