Level Up

法一:题面给出了 k , 2 k , 3 k k,2k,3k k,2k,3k这些数,容易想到调和级数。于是尝试对于每个 k k k,我们取找出升级的每段(也就是对怪物序列进行划分,每一段的等级相同,相邻两段等级相差一),然后看这篇题解;所以以后遇到处理 ∑ i = l r [ a i > x ] \overset{r}{\underset{i=l}{\sum}}[a_i>x] i=lr[ai>x]这种式子就可以想根号算法

法二:转换考虑对象。考虑一个怪兽什么时候会被打到。一个感性的想法就是 k k k越大,需要打的怪兽就越多,于是到同一个怪兽的等级就越低,怪兽就会从逃跑变成应战。于是有一个很自然的想法,设 f [ i ] f[i] f[i]表示第 i i i个怪兽应战的最低的 k k k。求 f [ i ] f[i] f[i]的时候,只需二分 k k k,并查找 1 1 1 ~ i − 1 i-1 i1中的 f ≤ k f\leq k fk的个数,设为 c n t cnt cnt,如果 ⌊ c n t k ⌋ + 1 ≤ a i \lfloor\frac{cnt}{k}\rfloor+1\leq a_i kcnt+1ai,那么这个 k k k就可以,否则就不行。上述过程可以用树状数组优化,时间复杂度为两个 log ⁡ \log log(当然遇到树状数组加二分可以想到树状数组加倍增,将时间复杂度优化为一个 log ⁡ \log log);然而我考试的时候是想到这里的,但是没有敢写,为啥?因为有另一种想法,就是 k k k越大,应战的怪兽就越多了,可能会抵消 k k k增大的影响,导致升级还是不会更慢(甚至更快),也就是说没有单调性(从数学表达式 ⌊ c n t k ⌋ \lfloor\frac{cnt}{k}\rfloor kcnt也可以看出来, k k k增大, c n t cnt cnt肯定也增大的),那么上述过程就错了;这个时候,考场就直接写嘛,这代码40行太好写了吧,这场rating纯属白给。重新做的时候想出来了单调性证明方法了。下面给出单调性证明:设 k 1 > k 2 k_1>k_2 k1>k2,那么当我们等级变成 2 2 2的时候,肯定是前者所在的怪兽的下标更大,此时我们将所有等级为 1 1 1的怪兽移除(相当于这些怪兽没有用了),然后再计算 k 1 , k 2 k_1,k_2 k1,k2两种情况下,我们等级为 2 2 2的地方。不难知道,此时对于 k 1 k_1 k1,下标更大了,而且由于 k 1 > k 2 k_1>k_2 k1>k2,说明我们对怪兽的需求数量也更大了,于是可以知道升到 2 2 2级的坐标肯定会更大。其余情况同理可证

法三:法二给出了单调性证明。现在考虑只求一个怪兽的 f f f,那么直接二分,并且每次暴力循环,时间复杂度为 O ( n log ⁡ n ) O(n\log n) O(nlogn);如果现在要对 n n n个怪兽求解,时间复杂度就是 O ( n 2 log ⁡ n ) O(n^2\log n) O(n2logn);遇到这种“单个二分没问题整个二分就超时”就可以上整体二分了

  • 17
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值