原题链接
题目大意:
现在有 n 个敌人,第 i 个敌人的初始攻击力为正整数 a i 。初始生命值
为正整数 W 。
定义如下流程为一场战斗:
从第 1 个敌人开始,每个敌人依次循环进行攻击。第 i 个敌人发起攻
击时,生命值 W 减去 a i ,同时 a i 翻倍。
当 W ≤ 0 时,本场战斗立刻结束。然后重置生命值 W 以及所有敌人
的攻击力 a i 。定义本次战斗的评分为接受敌人攻击的次数(不包括致
命攻击)。
q 次询问,每次询问给出三个数 l , r , d ,表示对第 [ l , r ] 个敌人进行强化,
使每个敌人的 a i 增加 d ,然后立刻进行一场战斗。输出此次战斗的评
分。
询问之间相互影响。
解题思路:
那会在比赛的时候是没想出来的,暴力也没打,这道题感觉还行。
我们可以设所有垃圾桶当前攻击力总和为S。先考虑暴力做法,毕竟暴力出奇迹,因为当前生命值W≤10e18,攻击力是翻倍递增的,因此最多只会打log W轮。因此暴力的时间复杂度为O(nq logW) ,可以获得20pts。
接下来考虑正解。
假设这场战斗完整地打了 k 轮,那么这 k 轮需要消耗的生 命值为 S × (2 0 + 2 1 + · · · + 2 k − 1 ) = S × (2 k − 1) 。 即要求出最大的 m ,使得 ∑ m i =1 a i ≤ W − S × (2 k − 1) 。 答案即为 k × n + m 。显然,对于每一次修改, S 只会增加 ( r i − l i + 1) × d i。 对于每一个询问,我们需要求出最大的 k 。 发现 k 不需要每次都枚举,因为每次操作后,答案只会变小,也就是 k 是递减的。 对于相同的 k 递减。于是用指针维护 m 的值,同时用两个差分数组维护区间加即可。对于不同的 k ,暴力求解即可。
时间复杂度 O ( n log W + q ) 。