1 条题解
-
0
题目大意
有一个 层的地牢,从第 层到第 层需要消耗能量 。每层有治疗泉,在第 层花费 金币可以增加 点能量(不能超过最大能量 )。每个玩家从 层出发到 层,初始能量为 ,求最小金币花费或判断是否可行。
算法思路
核心观察
- 可行性判断:如果从 到 中某段 ,则不可行。
- 贪心策略:在需要补充能量时,应该选择之前经过的层中 最小的治疗泉。
- 离线处理:将所有查询按照起点分组处理。
关键技巧
1. 预处理
- ST表:预处理 的区间最大值和 的区间最小值,用于快速查询
- 前缀和: 表示从第 层到第 层的能量消耗总和
2. 关键层确定
对于每个查询 :
- 找到关键层 :在区间 中 最小的层
- 在关键层 处补充能量到刚好能到达 层
3. 树状数组优化
- 使用 BIT 维护不同能量需求下的费用
- 从后往前扫描,维护一个单调栈来找到"下一个更便宜的泉"
算法流程
-
预处理:
- 读入 ,计算前缀和
- 构建 ST 表用于区间最大值/最小值查询
-
查询预处理:
- 对于每个查询,先判断可行性
- 找到关键层 ,计算基础花费
- 将查询离线存储
-
离线处理:
- 从后往前扫描每一层
- 维护单调栈保证 递增
- 用 BIT 维护费用信息
- 处理以当前层为起点的查询
-
输出答案
复杂度分析
- 时间复杂度:
- ST 表预处理
- 单调栈 + BIT 操作
- 查询处理
- 空间复杂度:
关键实现细节
单调栈维护
std::stack<int> sta; sta.push(n + 1); for_(i, n, 1) { while (B[i] < B[sta.top()]) { // 弹出栈顶,更新BIT } // 当前层入栈,更新BIT }
费用计算
- 基础费用:在关键层 补充 点能量
- 额外费用:通过 BIT 计算其他层的补充费用
总结
本题是一个综合性的优化问题,主要技巧包括:
- ST表快速区间查询
- 离线处理优化多次查询
- 单调栈维护下一个更便宜的治疗泉
- 树状数组高效维护费用信息
- 贪心策略选择最优治疗时机
- 1
信息
- ID
- 3145
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者