[ABC249F] Ignore Operations Solution

更好的阅读体验戳此进入

题面

存在变量 x,初始时 x=0。给定 n 次操作按序进行,存在两种,1 y 表示 xy2 y 表示 xx+y,你可以从中删除不超过 k 个操作,要求最大化操作后的 x,输出最大值。

Solution

这题比 E 简单多了。。 观察发现如果有一个 1 操作被我们保留,那么它将覆盖所有在其之前的操作。所以我们不难想到可以考虑以每个 1 操作为分割点,考虑是否保留这个操作。

显然我们希望让这个东西无后效性,所以具体地,我们将整个操作逆序遍历。如果为 2 操作则记录,如果为 1 操作则先假设我们保留这个操作,那么之后的所有都可以忽略了。此时我们只需要在前面记录的所有 2 操作中的所有负数中找到前 k 小的将其删除,此时剩下的即为当前的最优操作。然后考虑如果不保留这个操作,此时首先需要保证 k>0,然后令 kk1,也就是将这个 1 操作删除,只剩下后面的 2 操作,然后按照刚才的做法继续遍历下去。

有个细节就是注意当删 1 操作的时候已经把 k 用完了之后,就应该直接 break 了,因为此时无法将当前的 1 删掉,自然后面的所有操作就无效了。

然后我们刚才找到前 k 小的和这个操作,不难想到用平衡树或者权值线段树就行。权值线段树比较好写一些,但是注意需要离散化做个映射。具体地,权值线段树维护每个位置有多少个数,以及区间和,查询的时候就是在权值线段树上二分即可。

显然这个东西的复杂度最坏是 O(nlogn) 的。

然后还有两个老生常谈的 AtCoder 独有的问题,一个就是 C++17 似乎不支持 basic_string < pair < int, int > >,大概的原因时 is_trivial < pair < int, int > >::valuefalse,所以会报 CE,这个东西在 [ABC248Ex] Beautiful Subsequences 题解 也提到过。然后就是 AtCoder 里面 data 似乎时保留字符。

Code

UPD

update-2022_11_30 初稿