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\) 排序后,怪物爆炸的最小伤害就是:

\[\max_{i = 0}^N \left(\ell \cdot \sum_{j = 0}^i H_j - S_i \right) \]

证明:把 \(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)\)

posted @ 2025-08-14 11:29  CTHOOH  阅读(11)  评论(0)    收藏  举报