每次相当于创建一个包含 \(p_i,q_i\) 各自所在集合的点的大点 \(u\),然后 \(u\) 向 \(p_i,q_i\) 各自所在集合连边,边权就是胜率。
连完之后求每个点到根结点(\(\{1\sim n\}\))的路径边权和。
定义 \(L_i\) 为杀至少 \(i\) 个怪物至少需要多少护身符。如果求出 \(L_0\sim L_n\),可以二分求出问题的答案。
先固定 \(i\),看怎么求 \(L_i\)。我们不求 \(L_i\),求 \(m-L_i\),即杀至少 \(i\) 个怪物至多不选多少护身符。
设 \(c_j\) 为 \(1\sim i\) 中类型为 \(j\) 的怪物攻击力总和。如果不选 \(j\) 护身符,意味着承担 \(c_j\) 的伤害。可以贪心,优先抛弃 \(c\) 较小的护身符,直到抛弃的护身符 \(c\) 总和超过 \(H-1\)。此时的数量就是 \(m-L_i\)。
知道了怎么求一个 \(L_i\),看一下怎么求连续的 \(L\)。发现当 \(i\leftarrow i+1\),\(c\) 数组其实只有 \(c_{b_{(i+1)}}\) 增加了。
我们可以用两个平衡树维护当前已选护身符的集合 \(S\) 和未选集合 \(T\),每次有 \(c\) 增加了,只会使一个元素变动。
标签:ABC,边权,314,护身符,怪物,集合,sim From: https://www.cnblogs.com/FLY-lai/p/18012026