zoukankan      html  css  js  c++  java
  • 雨林跳跃[APIO2021]

    https://www.luogu.com.cn/problem/P7599

    题解

    考虑找到 ((B,C)) 区间内的最高树 (M)([C,D]) 中的最高树 (N)

    那么最后一步跳跃一定是从某棵满足 {(H_M le H_T le H_N)} 且 {((T,M)) 中没有比 (T) 更高的树} 的树 (T) 跳进 ([C,D]) 区间中

    我们把所有这样的树 (T) 叫做"准终点"

    所以原问题的目标就等价于用最少的步数跳到一个准终点上 然后再跳一步进入 ([C,D])

    ([A,B]) 中的哪棵树开始?

    如果 ([A,B]) 中存在一个准终点,那么显然可以直接从那棵树出发,只需一步即可完成

    否则,最优方案应该从 ([A,B]) 中满足 {((P,M)) 中没有比 (P) 更高的树} 的树中最高的那棵 (P) 开始 下面给出证明

    如图,(R)(P) 向左跳一次到的那棵树,(Q) 是向右跳一次到的那棵树

    由于上文假设 ([A,B]) 中没有合法的准终点 ,所以树 (R) 比 树 (N) 更高,所以向右跳一次一定会到达 (D) 右边,因此 ([A,R]) 区间的树都不能作为起点

    对于 ((R,P)) 区间的树,它们的高度全部小于 (H[P])。如果想要跳出 ((R,P)) 区间,不论怎么跳都会到达 (R,P) 其中一棵树,一定没有从 (P) 开始优

    对于 ((P,Q)) 区间的树同理,一定会跳到 (P,Q) 其中一棵树,然而 (P) 只需一步就能跳到 (Q) ,所以一定没有 (P) 优秀

    所以从 (P) 出发一定最优,QED

    如何找到最优出发点?

    从第 (B) 棵树开始,倍增地向左跳,跳到最左边的一棵在 (A) 之前并且高度小于树 (N) 的树,它就是最优出发点

    如果它是准终点,那么只需一步,否则需要多步

    (P) 出发怎么跳最优?

    对于一棵树,可以向左跳或者向右跳,我们把跳到左右中较高的一棵树称作跳高边,反之叫跳低边

    有如下跳的策略:

    • 如果当前树既可以向左跳又可以向右跳,并且向左右跳到的树高度都小于树 (M) ,那么优先跳高边(我们希望用尽量少的步数使当前高度增加)
    • 如果某时刻跳高边会使得跳到的树高度大于等于树 (M) ,那么验证一下跳高边到的那棵树是否是一个准终点,如果是那么就直接跳到它
    • 否则就总是向右跳,跳到一个准终点为止(如果跳不到说明无解)

    容易发现这就是最优策略

    实现时先从最优出发点出发,倍增跳高边跳到最高的一棵高度小于树 (M) 的为止 假设是树 (X)

    检查从 (X) 跳高边到的那棵树是不是准终点

    如果不是,那就从 (X) 出发倍增向右跳跳到最高的一棵高度小于树 (M) 的为止,然后检查它向右跳一步是不是准终点

    所有的步骤都可以使用ST表或者倍增实现,所以总时间复杂度是 (O((n+q)log n))

    作者:AK_DREAM
    本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    企业nginx应用实例(功能拆分记录)
    Squid代理服务器的安装与配置
    关于mysql主从架构master宕机后,请求转移问题解决办法
    记一次innobackupex备份恢复数据库过程
    elasticsearch6.6及其插件安装记录(较详细)
    redis一主二从加哨兵
    nginx反向代理proxy_pass的问题
    spring程序打包war,直接通过-jar启动,并指定spring.profiles.active参数控制多环境配置
    Debian下配置防火墙iptables
    内连接和外连接
  • 原文地址:https://www.cnblogs.com/ak-dream/p/AK_DREAM121.html
Copyright © 2011-2022 走看看