Day 62 贪心专项
F 还没来得及看,不想看了。
A
显然你可以用一个堆直接贪心,将每组牛按照 \(s\) 分类,直接扫过去,当加入 \(s=i\) 的牛的时候,现在还在堆里的牛显然就有相同的起点,则其终点越近越优,所以加入牛 \((e,m)\) 的时候判断当前容量是否足够,如果不够是否需要弹出一些牛加入 \((e,m)\),这取决于 \(e\)。
复杂度 \(O(K\log K)\)
B
第一问是容易的,每次用一个优先队列贪心删去度数最小的点(重复,直到最小度数变大),然后更新答案。
第二问不难想到也用优先队列贪心做一个近似算法,每次删去度数最大的点重复直到所有点度数是零。
C
首先有一个 naive 的贪心
将 \(a\) 排序,建立超级父亲 \(0\),按照 \(i:1\to n\),每次将父亲尚未分配的元素拿出最大的 \(sz_i\) 个,并将其中的最小值分配给自己,重复操作即可。
在 \(d\) 互不相同时显然正确。
但是可以发现有如下情况:
/ \
x x
/
x+1
可以变成
/ \
x x+1
/
x
这样就没了
那考虑贪心,将 \(a\) 排序,设 \(c[i]\)为 \(a[1,i]\) 还有多少个数字尚未确定归属,从大到小
然后按 \(1\to n\) 确定这个位置是数是什么,也就是 \(b[i]\) 填 \(a[j]\) 的要求是 \(\ge a[j]\) 的个数是\(\ge siz[i]\) 的
然后填了就相当于区间减。
详细地说,我们线段树维护区间最小值再二分找到第一个合法的 \(a[j]\),并且取出其未使用的最靠后的位置(减小限制),接着将后面全部减去 \(siz[i]\)。
当开始填 \(i\) 的儿子的时候(也就是第一次进入子树的时候),将 \(siz[i]-1\) 加回之前的位置表示限制已经消除(可以不考虑这个限制,并且我们需要使用这 \(siz[i]-1\) 个元素来填进去了)。
D
不难发现有且仅有 \(deg\le 2\) 的点能够作为根,当这类点不是根的时候也可以任意选择子树是左儿子还是右儿子来决定顺序。
也即这类点一方面可以作为根,一方面可以决定其与子树的输出关系
所以可以先钦定 \(deg\le 2\) 且编号最小的点为根,这个点如果不是根也必然是第一个输出的。
求子树内可以第一个输出的数字的编号最小值。
然后根据这个值分类讨论构造即可。
E
可以发现 \(a_i\le b_i\) 的机器都对 \(0\) 号机器人有威胁,解除威胁有三个决策:
- 让 \(a_i+1\) 干掉它,代价是 \(1\)。
- 让另一类球干掉它
- 自己转移掉球到无穷
可以看出第三类决策显然是最劣的,而如果需要使用第二个决策那必然只会用一类球干掉所有的非法球。
所以可以枚举这个特殊球,其需要有 \(a\le b\) 用 \(b-a+1\) 次改到无穷让它滚到 \(1\),解决所有它前面的有威胁的机器人,后面的就用 \(1\) 的代价解决。
至于有威胁的机器人怎么求,其实是 \(a>b\) 的机器人,\([a-b,a]\) 没有一个覆盖到它的那种。
G
考虑到本质上就是让最终所有点的入度出度都是 \(1\),且连通。
那么每个点首先优先保留最大的入度点,其余断掉,然后合理分配成环,就可以做到若干环,出入度都是 \(1\),这里显然是下界。
然后考虑合并环,找连向同一个点的原环边和非环边进行切开连起来就行了。