考前写题解增加RP。
D1T1:
考虑按照列DP。对于每一列选择的鱼的区间进行决策。每列中被选择的y坐标最大的鱼,需要被左面或右面覆盖。
假设我们决策好了前i列的方案,考虑第i列被选择的y坐标最大的鱼是否被第i-1列覆盖。
若没有覆盖,需要记录i列中选择的y坐标最大值。此时他需要被第i+1列覆盖,因此第i列无法覆盖到第i+1列,于是无需记录第i列的覆盖高度。
若被覆盖,需要考虑第i列可以覆盖到第i+1列的高度,因此我们记录第i列选择的y坐标最小值,他-1就是最大覆盖高度。
再额外记录第i列没有选择任何鱼的状态。
转移用双指针和后缀max优化下,除去排序复杂度线性。
D1T2:
考虑我们询问A的数值,若他是1或n,则直接结束,否则我们在黑板上记录A的位置,下一次询问B即可。
由于黑板值域有限,我们将2~n-1分成k段,记录A的所在段。
下一次询问B时,根据黑板上的数字,判断出A的所在区间[l,r],若b<=l或b>=r,则直接结束。否则继续分段,并记录b的所在位置,下一次询问A,以此类推。
我们需要记录目前进行的轮数,根据他的奇偶性可以决定当前询问A还是B。
以询问A为例:我们可以根据a的值,判断出上次询问B时的区间[l',r']。
此时,我们若知道B所在的[l'+1,r'-1]分出的子区间的编号s(0<=s<k),即可算出当前的[l,r],并根据a的值继续算法流程。
因此我们记录轮数以及上一次的s(子区间编号)即可。值域是\(O(k*log_k{n})\)的。取k=3可以达到21。
我们发现,最后一轮最多剩下6个数,除去左右还剩下4个,分成2段就可以了,因此最后一轮取k=2,就可以达到20了。
D1T3:
太难了。
D2T1:
容易发现,题目等价于每个节点选择一个儿子并继承他的颜色。
我们考虑最终方案,一定是连成一条根到黑色叶子的路径。路径外的点方案随意。
因此,我们对于每个叶子,求出删除他到根路径上的点后,剩下的点的儿子个数乘积即可。
询问相当于求出黑色叶子的权值和。修改操作用线段树维护。\(O(qlogm)\)。
D2T2:
考虑给出x,对于每种昆虫,保留\(\min(出现次数,x)\)个,求保留下来的个数。
我们只需要依次把每只昆虫加入,并判断一下众数,若众数>x,就把这只昆虫移除。
先对于x=1执行一次,求出种类数c。之后我们二分答案,找到最大的满足保留下来的个数=x*c的x即可。
可以获得76分。
考虑优化:设当前check了x。
若答案>=x,则成功加入的昆虫,之后也可以加入,因此我们只保留加入失败的昆虫即可。
若答案<x,则加入失败的昆虫不可能在之后成功加入,因此我们只保留成功加入的昆虫即可。
这样每次需要考虑的昆虫集合会缩减一半,算上最开始的一次,总共次数约为3n次。
根据实现细节可以获得99~100分。
D2T3:
首先,若一个岛没有出边,则到达它就回不去了,因此要把它删除。
重复执行这个类似拓扑排序的过程,直到所有点均有出边。
考虑当前点(初始为0)的出度:
出度0,无解。
出度>=2,我们选择一条出边一直走下去,一定可以绕出环(因为所有点都有出边)。
在环上顺时针走一圈后,原路返回。
然后,选择另一条出边一直走下去。
若走到了刚才绕出的环上,我们逆时针走一圈,原路返回。算法结束。
否则,我们也在环上顺时针走一圈,原路返回。然后把这个过程重复一遍,绕环的方向改为逆时针,即可恢复到初始状态,算法结束。
出度1,我们只能先走这条边,并在后续过程结束后再返回。也就是把这条边反向,同时这个点出度变成了0,将其删除。最后更改当前点。
注意删除一个点时需要考虑指向他的点的出度变化。
为了方便实现,可以使用set维护出入边,复杂度\(O(nlogn)\)。