如何通过E. Level Up实现技能提升?
摘要:E. Level Up 题意 玩家初始等级为 (1), 有 (n) 只怪物,每个怪物有一个等级 (a_i), 如果怪物等级高于你,则你们会战斗,战斗后经验加1,否则怪物会逃跑,你不会获得经验,每 k 点经验就会升级。给你 (q
E. Level Up
题意
玩家初始等级为 \(1\), 有 \(n\) 只怪物,每个怪物有一个等级 \(a_i\), 如果怪物等级高于你,则你们会战斗,战斗后经验加1,否则怪物会逃跑,你不会获得经验,每 k 点经验就会升级。给你 \(q\) 个询问,给个询问给出 \(i,x\), 问你当 \(k = x\) 时,会不会发生战斗(即问你你的等级会不会小于等于此时的\(a_i\)
\(1≤n,q≤2⋅10^5, 1≤ai≤2⋅10^5, 1≤i,x≤ n\)
听说根号分治的 sqrt 会被 hack,这里讲一个\(nlognlogn\)的做法
可以根据\(q\),问的是到\(i\)时\(k = x\)时的\(lv\)会不会小于等于\(a_i\), 因为lv与k是反比例关系,k越小,lv就会越高,对于每个位置处理出如果能发生战斗所需要的最大的k,记为\(b_i\), 如过\(b_i <= x\), 则可以说明,比能发生战斗所需的k还大,则到这个位置的lv会比\(a_i\)还小,则会发生战斗(因为是反比例函数,你求得是最大上界,小于k的都会比\(a_i\) 大,这里要仔细想一下
因为这样k具有单调性,比当前界限大的话,lv会变小,则以后战斗的怪只会增加不会减少,我们可以二分一个最大的mid, 满足在这个位置的战斗的怪所能到达的等级小于等于\(a_i\), mid - 1位置的战斗的怪所能到达的等级都大于\(a_i\), 因为是反函数。
现在我们需要一个数据结构来维护,在一段k的范围内加 1,这里记为k能战斗的数量(经验值),询问某个位置的数量(经验值),来当作二分得\(check\)函数计算等级, 也就是区间修改和单点查询,这里可以用线段树维护(树状数组也是可以得)。最后二分出的位置记录下来,当查询的判断,修改时修改的是大于等于答案的位置,因为大于等于的位置k越大,lv越小,战斗的次数越多。
