雨林跳跃[APIO2021]
https://www.luogu.com.cn/problem/P7599
题解
考虑找到 区间内的最高树 和 中的最高树
那么最后一步跳跃一定是从某棵满足 {} 且 { 中没有比 更高的树} 的树 跳进 区间中
我们把所有这样的树 叫做"准终点"
所以原问题的目标就等价于用最少的步数跳到一个准终点上 然后再跳一步进入
从 中的哪棵树开始?
如果 中存在一个准终点,那么显然可以直接从那棵树出发,只需一步即可完成
否则,最优方案应该从 中满足 { 中没有比 更高的树} 的树中最高的那棵 开始 下面给出证明
如图, 是 向左跳一次到的那棵树, 是向右跳一次到的那棵树
由于上文假设 中没有合法的准终点 ,所以树 比 树 更高,所以向右跳一次一定会到达 右边,因此 区间的树都不能作为起点
对于 区间的树,它们的高度全部小于 。如果想要跳出 区间,不论怎么跳都会到达 其中一棵树,一定没有从 开始优
对于 区间的树同理,一定会跳到 其中一棵树,然而 只需一步就能跳到 ,所以一定没有 优秀
所以从 出发一定最优,QED
如何找到最优出发点?
从第 棵树开始,倍增地向左跳,跳到最左边的一棵在 之前并且高度小于树 的树,它就是最优出发点
如果它是准终点,那么只需一步,否则需要多步
从 出发怎么跳最优?
对于一棵树,可以向左跳或者向右跳,我们把跳到左右中较高的一棵树称作跳高边,反之叫跳低边
有如下跳的策略:
- 如果当前树既可以向左跳又可以向右跳,并且向左右跳到的树高度都小于树 ,那么优先跳高边(我们希望用尽量少的步数使当前高度增加)
- 如果某时刻跳高边会使得跳到的树高度大于等于树 ,那么验证一下跳高边到的那棵树是否是一个准终点,如果是那么就直接跳到它
- 否则就总是向右跳,跳到一个准终点为止(如果跳不到说明无解)
容易发现这就是最优策略
实现时先从最优出发点出发,倍增跳高边跳到最高的一棵高度小于树 的为止 假设是树
检查从 跳高边到的那棵树是不是准终点
如果不是,那就从 出发倍增向右跳跳到最高的一棵高度小于树 的为止,然后检查它向右跳一步是不是准终点
所有的步骤都可以使用ST表或者倍增实现,所以总时间复杂度是
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现