P11989 笔记
题目大意
有 \(N\) 个怪物,第 \(i\) 个怪物强度为 \(P_i\),在 \(S_i\) 时刻出现,有 \(H_i\) 的血量。
勇者每秒可以对某个怪物造成 \(1\) 点伤害,当怪物血量降为 \(0\) 时就被打败了,后续不能再攻击它。在 \(T\) 秒时,所有怪物会一起爆炸,爆炸的攻击力为 \(H_1P_1 + H_2P_2 \ldots + H_NP_N\)。
现在有 \(Q\) 次询问,每次询问给出勇者的血量 \(M\),你需要求出勇者能挑战的最高难度 \(\ell \in [0, L]\)。在 \(\ell\) 难度下,所有怪物的血量变为原本的 \(\ell\) 倍,你需要确保该难度下勇者血量不会降为负数。
思路
假设 \(\ell\) 确定,一个贪心策略就是每秒选择场上存活的 \(P\) 最大的怪物攻击,则可以做到 \(O(N \log N)\)。
但是这就不是很好优化了,考虑拆贡献,将 \(P\) 排序并去重后的数组记为 \(\{B_M\}\)。枚举 \(i\) 并将所有 \(P_j \ge B_i\) 的怪物拉出来,这个时候只需要看能最多攻击多少次,再将攻击次数乘上 \(B_i - B_{i - 1}\) 就行了(设 \(B_0 = 0\))。
这个不是很好理解,胡了一段:首先把 \(=B_M\) 的 \(P\) 拉出来单独算贡献,算完它们的贡献,它们就和 \(B_{M - 1}\) 没有区别了,于是就可以把它们一起做,权值为 \(B_i - B_{i - 1}\)。
于是现在转化为了 \(P_i = 1\) 的情况,这种情况下,我们把每个 \((S_i, H_i, 1)\) 的怪物拆成 \(H_i\) 个 \((S_i, 1, 1)\) 的怪物,容易发现这是等价的,并时光倒流,把 \(S_i\) 变为 \(T - S_i\),这样就相当于 \([0, S_i)\) 时间能攻击 \(i\) 了。按 \(S_i\) 排序后,怪物爆炸的最小伤害就是:
证明:把 \(1 \sim T\) 这 \(T\) 个时间点看作左部点,\(\sum H_i\) 个怪物看作右部点,接着第 \(i\) 个时间点向所有 \(S_j \ge i\) 的点连边,对这个图做最大匹配就是能造成的最大伤害,于是用霍尔定理可以得到上面的式子。
于是记 \(W_i = \sum_{j = 0}^i H_i\),最小伤害就是 \(\max_{i = 0}^N \left(\ell \cdot W_i - S_i\right)\),这就是 \(N + 1\) 个一次函数形成的上凸壳,可以用栈 \(O(N)\) 求出。
最后将其乘上 \(B_i - B_{i - 1}\) 的权值后,差分一下即可。
总时间复杂度 \(O(N^2 + L + Q\log L)\)。

浙公网安备 33010602011771号