题解 NOI2019 序列

最近打了场CF,发现那个E2很眼熟,经过yg的提醒意识到和这题有点类似,所以就来写这题了……

有个看一眼就能想到的假做法是这样的:先选(L)(a+b)最大的,再选(K-L)(a)最大的和(K-L)(b)最大的。

这时候你会发现这样一组数据:

3 2 1
50 50
0 52
200 0

这样选我们会选({200,0},50,52),实际上我们应该选({50,50},52,200)

发现主要矛盾在于大带小,而这个小的应该舍弃。

那我们考虑先钦定一些,再用更优的替换。

假如我们按照上面那种贪心先钦定好了选择的树,然后我们从第(L+1)组开始往后找每一组进行替换。

1.这组(a_i,b_i)都没有被选过

如果现在成对的数量恰好是(L)

如果我们两个都选,可以拆一组(+)替换一个零散的,或者替换两个零散的;如果我们两个只选一个,那只能替换一个零散的。

如果现在成对的数量(gt L)

首先恰好是(L)时的替换方法肯定是可行的,然后两个都选还可以拆两组,只选一个还可以拆一组,但是要实时更新成对的数量。

这个直接拿堆或者(multiset)维护就能找到最小的,然后插进去替换。

2.这组(a_i,b_i)有一个被选过

假设选了(a_i),则把(b_i)和当前选过的最小的(b_i)进行比较,如果比它大就把它换下来。因为不管前面是拆了一组还是换了零散的,成对的数量肯定不会减少,所以这样做肯定是对的。如果选了(b_i)就同理换(a_i)。然后实时更新现在成对的数量。找最小和上一种情况一样。

原文地址:https://www.cnblogs.com/Kylin-xy/p/tijie-NOI2019D1T3.html