CF1329 简要题解
垃圾 pretests,啥都卡不了,干脆改 OI 赛制算了 = =
美妙的 FST 场,连挂两题,\(+106\rightarrow -123\),俯冲橙名 \(\sqrt{}\)
- A
我会 PP!
随便写一个能过样例的贪心就可以过 pretests 啦,是不是非常简单呢?
首先显然 \(\sum l_i< n\) 的时候无解。
考虑第 \(i\) 种颜色,为了让在它之前的 \(i-1\) 种颜色都至少有一格剩余,应该有 \(l_i\leq n-i+1\),否则也无解。
猜想剩余情况一定有解,并考虑下面的构造:
从后往前考虑每种颜色,并将它放在可能的最靠右的位置上。具体来说,第 \(m\) 种颜色的左端点 \(p_i\) 一定会放在 \(n-l_i+1\) 的位置上。对于第 \(i\) 种颜色,可能的最靠右的位置是 \(p_{i+1}-1\),但是可能会有 \(\sum_{j=1}^{i-1} l_j < p_{i+1}-2\) 的情况,这种时候需要令 \(p_i=1+\sum_{j=1}^{i-1} l_j\)。正确性显然。
- B
还算有趣的题目,也是我唯一一道过掉的题目。
先感性理解下这个序列大概长什么样子。
设 \(a_1=x, a_2=y\),那么有 \(y>x, y\oplus x>x\)。很容易发现,如果 \(x, y\) 的最高的 \(1\) 位置相同,那么异或之后这一位必然是 \(0\),不可能有 \(y\oplus x>x\)。而如果 \(x, y\) 最高的 \(1\) 位置不同,由于 \(y>x\),异或之后保留了 \(y\) 的最高的 \(1\),必然有 \(y\oplus x>x\)。由数学归纳法可以得知,\(b_i\) 的最高的 \(1\) 位置与 \(a_i\) 是相同的。
因此题目中的条件就可以写成,最高的 \(1\) 位置严格递增,且 \(a_n\leq d\)。注意到 \(a_n\) 的最高位与 \(d\) 不同时,我们只关心最高位的位置,并不关心低位的值。
所以 \(n\leq \log_2 d\),可以记录最高位的位置之后暴力 dp。
- C
我会 PP!
只要贪心地模拟每次删根的过程,删不动再递归到儿子就可以过 pretests 啦,是不是非常简单呢?
实际上上面这个做法的确可以 AC,前提是清空没假 /cy
考虑数学归纳法证明:
若当前节点 \(r\) 为叶子,则显然将它删除(如果可以的话)最优。
否则,设两个儿子的根分别为 \(x, y\),且 \(y<x<r\)。假设我们已经证明了在 \(x, y\) 的子树中分别贪心地删根是最优的,比较一下此时删 \(x\) 和删 \(r\),发现删完之后堆的形态完全相同,唯一的区别是根的位置分别是 \(r\) 和 \(x\)。显然保留 \(x\),删掉 \(r\) 更优。
此时如果删 \(y\),发现 \(y\) 的位置只会变得更小。换句话说,删 \(y\) 只会让 \(y>x\) 的时刻更加推迟。考虑先删 \(r\),发现在 \(y>x\) 之前,不会对 \(y\) 所在的子树造成任何影响。也就是说,如果将删 \(y\) 和删 \(r\) 的过程调换,完全不会影响答案。因此如果最优解是先删 \(y\),我们完全可以先删 \(r\),直到 \(y>x\) 为止,再考虑 \(y\) 子树的事情。发现这个时候其实可以将 \(y, x\) 调换,因此用上面的结论,我们可以知道先删 \(y\) 一定不优。
所以这题怎么就成了 1C 难度了……如果放到 1A/B 位置,反而可能会更简单(因为猜结论胆子更大了x
顺便提一句,判断根是否能删的时候,可能会访问叶节点的儿子,因此开数组和清空的时候,范围最好都大点,否则就……
- D
这题思维难度基本上没有……实际上代码难度也不高,但是我还是没敢写(要不然也不至于掉那么多呜呜
我们将 \(s_i=s_{i+1}\) 的 \(i\) 称作 “隔板”,隔板 \(i\) 的颜色为 \(s_i\)。
考虑一次删除的过程,发现必然可以删掉某个颜色 \(x\) 的一个隔板(指删掉这个隔板的两个组成元素中的一个,从而破坏这个隔板)。同时,如果 \(x\) 以外的颜色也存在隔板的话,显然可以找到连续的两个隔板,其中恰有一个颜色是 \(x\)。由于中间不存在其他隔板,所以可以同时破坏这两个隔板。可以发现,如果只存在一种颜色 \(x\) 的隔板的话,无论如何,一次也都只能删除一个隔板(或者删除两个隔板后再产生一个新的)。
因此这形成了一个经典的贪心:每次删掉出现次数最多的颜色的某个隔板,再随便拉一个颜色不同的,与它相邻的隔板。正确性显然。
现在的问题有两个,如何找到这样的隔板和如何输出方案。
找隔板的时候,如果只是随便地在这个颜色中选一个,可能会出现两边都是同色隔板的情况。因此需要对每个颜色 \(x\) 维护一个集合,集合中每个元素都是一对相邻隔板,满足恰好一个颜色为 \(x\)。因此每次操作的时候,从这个集合里任选一个,并更新删去的隔板影响的集合即可。显然这一过程的操作总数是 \(O(n)\) 的。
输出方案时,可以维护每次删去的子串在原串中的左右端点。输出时,只需要用一个树状数组维护在这个端点前被删去的长度即可。然后用并查集将区间内未删去的位置删掉,可以发现操作总数也是 \(O(n)\) 的。
注意最后没有隔板时,一定还会剩下若干零散元素,需要再花费一次将它们删掉。
- E
这题我不会做,看了下官方题解,感觉说的好模糊啊……自己摸索着倒是也看懂了,详细整理下吧。
原问题可以抽象成,有若干元素 \(a\),满足 \(a_0=p_1, a_i=p_{i+1}-p_i, a_m=n+1-p_m\),将 \(a_i\) 分成 \(d_i\) 份,满足 \(\sum_{i=0}^m d_m= l=k+m+1\),并使得份之间的极差最小。
首先考虑对于一个确定的 \(a_i\) 和 \(d_i\) 如何细分;显然将它分成 \(a_i\bmod d_i\) 份 \(\lceil\frac{a_i}{d_i}\rceil\) 和 \(d_i-a_i\bmod d_i\) 份 \(\lfloor\frac{a_i}{d_i} \rfloor\) 最优。
再考虑一个理论上的最优解:设 \(L\) 表示不考虑每份的最大值,将 \(a\) 分成至少 \(l\) 份时,最大的最小值,\(R\) 表示不考虑每份的最小值,将 \(a\) 分成至多 \(l\) 份时,最小的最大值。这两个值是经典的二分答案问题,可以简单求解。发现答案不会小于 \(R-L\)。
对于每一个 \(i\),令 \(d_{i, L}\) 表示求 \(L\) 时,将 \(a_i\) 分成了 \(d_{i, L}\) 份,\(d_{i, R}\) 同理。根据二分答案的过程,有 \(d_{i, L}=\lfloor\frac{a_i}{L}\rfloor, d_{i, R}=\lceil\frac{a_i}{R}\rceil\)。
首先有一些观察:
-
\(\sum_{i=0}^m d_{i, L}\geq l, \sum_{i=0}^m d_{i, R}\leq l\)。
-
对于任意的 \(i\),\(\lfloor\frac{a_i}{d_i} \rfloor<L\) 当且仅当 \(d_i>d_{i, L}\);\(\lceil\frac{a_i}{d_i} \rceil>R\) 当且仅当 \(d_i<d_{i, R}\)。
这些都是由 \(L, R\) 的定义得到的。
这时候我们发现,对于任意的 \(i\),\(\lfloor\frac{a_i}{d_i} \rfloor\geq L\) 且 \(\lceil\frac{a_i}{d_i} \rceil\leq R\) 的充要条件是 \(\exists d_i\in [d_{i, R}, d_{i, L}]\),即 \(d_{i, R}\leq d_{i, L}\)。
换句话说,假如任意 \(i\) 都有 \(d_{i, R}\leq d_{i, L}\),那么我们必然可以构造一组 \(d_i\),使得极差为 \(R-L\)。注意我们还需要满足 \(\sum_{i=1}^m d_i=l\),但是由于 \(d_i\in [d_{i, R}, d_{i, L}]\),结合观察 \(1\),我们知道必然可以构造出满足条件的解(类似函数零点的证明)。
现在的问题是可能会存在若干 \(d_{i, R}> d_{i, L}\)。但是注意到 \(L\leq R\) 且 \(\lceil\frac{a_i}{d_i} \rceil-\lfloor\frac{a_i}{d_i} \rfloor\leq 1\),因此不会出现 \(\lceil\frac{a_i}{d_i} \rceil>R\) 且 \(\lfloor\frac{a_i}{d_i} \rfloor<L\) 的情况,也就是说,\(d_i\leq d_{i, L}\) 和 \(d_i\geq d_{i, R}\) 至少有一个满足。这可以推出 \(d_{i, L}=d_{i, R}-1\)。
由于对于这样的 \(i\),任意地选取 \(d_i\) ,都只会有恰好一个边界被对应的上下界卡住(\(\lceil\frac{a_i}{d_i} \rceil\leq R\) 或 \(\lfloor\frac{a_i}{d_i} \rfloor\geq L\)),我们选取满足两个条件的 \(d_i\) 各一个,并让另一个方向尽可能靠近对应的上下界。发现 \(d_{i, L}\) 和 $ d_{i, R}$ 刚好分别满足条件。
因此我们现在得到了这样的问题:有若干 \(x_i=\lfloor\frac{a_i}{d_{i, R}} \rfloor<L\),与之对应的有 \(y_i=\lceil\frac{a_i}{d_{i, L}} \rceil>R\)。我们要在每个 \((x_i, y_i)\) 中选择一个作为 \(w_i\),最小化 \(\max(R, \max(w_i))-\min(L, \min(w_i))\)。
这个问题比较好解决,只需要一开始将 \(L, R\) 和所有 \(y_i\) 加入集合,随后从大到小扫描每个 \(y_i\),将其删除,并加入 \(x_i\)。在这个过程中不断更新答案即可。最终可以构造出 \(\sum_{i=0}^m d_i=l\),证明与上面类似,这里不再提。
总复杂度 \(O\left(m(\log m+\log n)\right)\)。
写 CF 题解好累啊……想咕了(大雾