题解 CF1523H Hopping Around the Array

link

题意

数轴上有 n 个点,每个点有属性 ai,在第 i 个点可以花费 1 的步数移动至 [i,i+ai] 中任意一个点。定义一次操作为选出一个 i,使 aiai+1

q 组询问,每次给出 l,r,k,求有 k 次操作机会时,从第 l 个点走到第 r 个点的最小步数。各组询问相互独立,即操作没有后效性。

1n,q2×104,1ain,0k30

题解

可以先想一个暴力,用 fi,j,k 表示从 i 出发,走 j 步,至多操作了 k 次时能走到的最远点,查询时只需在 fl,x,k 上二分 x 即可,依据是每次转移是连续的,跳到一个大于 r 的点必定可以跳到 r

由此有转移方程 fi,j,k=maxk1+k2=k{maxs=ifi,j1,k1{s+as+k2}},原因也是能从若 i 走到 x,那 [i,x] 中的每个点都必定可以经过,即在其中取下一步的最远点,这个过程是 RMQ 问题,用 ST 表优化。

这样转移状态是 O(n2k) 的,发现查询时的二分本质上就是步数的倍增,我们只关注走了 2j 步的情况,改变 f 定义,fi,j,k 表示从 i 出发,走 2j 步,至多操作了 k 次时能走到的最远点。转移方程为 fi,j,k=maxk1+k2=k{maxs=ifi,j1,k1fs,j1,k2},初始化 fi,0,k=i+ai+k,直接枚举 k1,k2 转移,用 ST 表可做到 O(nk2logn+nklog2n) 预处理。

对于每次询问,类似倍增求树上 k 级祖先,从 logn 位开始从大到小考虑,令 gj,k 表示考虑完 [j,logn] 位,至多操作了 k 次时,l 能去到最远位置,若对于所有 k,均满足 maxk1+k2=k{maxs=lgj+1,k1fs,j,k2}<r,说明不存在任何转移方式可以通过这 2j 步走到 r,换言之这 2j 步是必走的,于是答案加上 2j,并更新 gj,k=maxk1+k2=k{maxs=igj+1,k1fs,j,k2},否则这 2j 步是不必要的,答案不变,并让 gj,k=gj+1,k

你发现每次询问都要预处理 logn 次 ST 表,单次查询复杂度是糟糕的 O(nklog2n),但是对于每组询问,f 是不变的,不必每次都预处理,于是把询问离线下来,对于每个 j 把每组询问都更新一遍即可。

总时间复杂度 O((n+q)(k2logn+klog2n)),空间复杂度 O(nklogn)

注意空间访问尽量连续,不知道会不会卡常。

posted @   Terac  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示