雨林跳跃[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)\)