APIO2021
雨林跳跃
-
设 \(X=\max([B,C-1]),Y=\max(C,D)\)
-
如果 \(X>Y\) 那么一定有解,否则一定有解
-
可以发现越跳越高,并且 跳跃一段路程时一定满足自己已经比这一段的所有树都高 ,才能跳过去
-
所以最后一步跳跃一定是从一个高度为 \(X\leq T<Y\) 树跳到右边的区间中,而且只可能从右区间的左边跳过去
-
一定有一个最优解以 \([A,B]\) 中最长的右区间 \([E,B]\) (满足区间最高的高度 < T)中的最高点为起点
-
因为一个点跳的时候必须满足跳过去的时候 <Y ,所以右边不能有 >Y 的树,所以先确定区间 \([E,B]\)
-
这个区间其实可以看成以右端点 \(B\) 为起点,每次跳 1 格判断是否 >Y ,那么可以用 倍增 + ST表 实现 \(\log\)
-
将已经 \(>Y\) 的树不看了,因为一定没有解
-
那么剩下的树中,可以发现以其他点为起点的最优解要么跳到某一步后会跳到最高点,要么就是某一步之前都可以直接替换成最高点来跳
-
所以我们就以小于 Y 的最高点为起点求答案
-
所以现在等同于我们知道了跳跃的起点,跳跃的目标是以最少的步数跳到高度 \(X\leq T<Y\) 的树
-
如果当前最高点已经满足要求了,那么可以直接返回 1
-
否则就需要求出到 \(X\leq T<Y\) 这种树的最少的步数,最后 +1
-
假设当前点不满足要求,也就是 \(< X\)
-
那么考虑下一步能跳到的两个地方,假设都 \(<X\) ,考虑哪个地方更优
-
在 \(<X\) 的树中,一定是跳的越高越好 ,可以通过分类讨论+画图发现
-
所以每次跳更高的树,当第一次遇到符合答案的高度时就可以直接跳到右区间了
-
注意到已经保证有解,所以这么跳一定会第一次遇到一个满足条件的树
-
但是可能在一颗树中的选择有一个满足条件,一个 \(>Y\) ,但是我们会跳到更高的树,不过这不影响答案,因为保证有解,所以我们跳到第一个 \(\geq X\) 的地方就说明出现了符合高度的树
-
确定了起点,每一步会跳到的树也确定了,目标是求多少步第一次跳到高度 \(\geq X\) 的树
-
那么显然可以倍增来做
-
虽然我写了代码,但是因为本人不知道洛谷的交互题怎么交,导致我无法确定代码的正确性,所以这个题就没有参考代码了
总结
-
倍增
-
其实这个题没有那么好想,很多性质需要去挖掘,需要先大胆猜测然后再尝试证明,直接看出来一个性质不是那么容易