Codeforces Global Round 19 题解

A

显然一个序列符合要求的充要条件是它是单调不降的,否则我们找出 \(a_{i+1}<a_i\)\(i\) 然后将 \([1,i],[i+1,n]\) 分别排序得到的序列就不符合要求。

B

由于数据范围很小,直接无脑区间 DP 硬上。

时间复杂度 \(n^3\log n\)

C

首先答案下界肯定是 \(\sum\limits_{i=2}^{n-1}\lceil\dfrac{a_i}{2}\rceil\)。并且容易发现如果有解,那么答案也是这个下界,因为石子肯定不会扔来扔去,要么直接扔到 \(1\)\(n\),要么先扔到一个大小为奇数的堆上再扔到 \(n\)

于是问题变为如何判断是否有解,稍微想想就可以发现如果存在一个 \(a_i(i\in[2,n-1])\) 是偶数,那么肯定有解,因为每次我们选择这个大小为偶数的堆丢给大小为奇数的堆总可以造出另一个大小为偶数的堆。而如果 \(n>3\) 且存在 \(a_i(i\in[2,n-1])\) 超过 \(2\) 那也是有解的,因为我们一步就可以造出大小为偶数的堆。唯一无解的情况就是 \(n=3\)\(a_2\) 为奇数,或 \(a_i=1(i\in[2,n-1])\)

D

记原序列为 \(A,B\)​。

首先,\(ans=\sum\limits_{i<j}(a_i+a_j)^2+(b_i+b_j)^2=\sum\limits_{i<j}(2a_ia_j+2b_ib_j)+\sum\limits_{i=1}^n(n-1)(a_i^2+b_i^2)\)​,后者显然是定值 \((n-1)\sum\limits_{i=1}^n(A_i^2+B_i^2)\)​,因此我们只用最小化前者即可。

注意到 \(\sum\limits_{i<j}2a_ia_j=(\sum\limits_{i=1}^na_i)^2-\sum\limits_{i=1}^na_i^2\),故 \(\sum\limits_{i<j}(2a_ia_j+2b_ib_j)=(\sum\limits_{i=1}^na_i)^2+(\sum\limits_{i=1}^nb_i)^2-\sum\limits_{i=1}^n(A_i^2+B_i^2)\),后面那个减号里的东西又是定值,而前面 \((\sum\limits_{i=1}^na_i)^2+(\sum\limits_{i=1}^nb_i)^2\),只要确定了 \(\sum\limits_{i=1}^na_i\) 就可以确定 \(\sum\limits_{i=1}^nb_i\),bitset 优化背包求出所有可能的 \(\sum\limits_{i=1}^na_i\) 即可。

E

首先考虑这样一个问题:给定 \(n\) 对数 \((x_i,y_i)\),要求 \(\max\limits_{i\ne j}(x_i+x_j)(y_i+y_j)\),发现不太好做。这意味着解决此题可能要用到 \(cnt\) 数组的性质:\(\sum\limits_xcnt_x=n\)

先考虑如果没有 bad pairs 怎么做。我们按 \(cnt\) 从小到大的顺序枚举 \(x\),那么不妨假设 \(cnt_y\le cnt_x\),我们再枚举 \(c=cnt_y\) 满足 \(c\le cnt_x\),那么显然我们希望 \(y\) 是所有 \(cnt_y=c\) 中最大的,这个直接开一个桶边枚举边取 \(\max\) 即可。

接下来考虑加上 bad pairs 的限制的情况,其实也好办,与之前唯一的不同之处在于,我们不能只取出 \(cnt_y=c\)\(y\) 中最大的,而要维护一个 multiset 装有所有这样的 \(y\),然后每次取出 multiset 中最大的,如果 \((x,y)\) 不是 bad pair 就更新答案并 break,否则再找次大的,以此类推。这里显然总枚举量是 \(\mathcal O(n+m)\) 的,因为每次扔掉最大的都对应一个 bad pair,而 bad pair 总共只有 \(m\) 个。

时间复杂度 \((n+m)\log n\)

F

一个略有点麻烦的做法。

首先考虑一种特殊的情形:如果我们以 \(1\)​ 为根 DFS 一遍整棵树,所有非根节点都满足父亲权值 \(\ge\)​ 当前节点的权值,如何解决这个问题。设 \(dp_i\)​ 表示覆盖以 \(i\)​ 子树内所有点,并且 \(i\)​ 子树内至少有一个点权值是 \(a_i\)​,最少需要多少的代价,那么有转移 \(dp_i=\sum\limits_{j\in\text{son}(i)}dp_j+\min\limits_{j\in\text{son}(i)}(a_i-a_j)\)​。容易发现这是个链剖分,具体来说就是以 \(i\)​ 的儿子中 \(a_j\)​ 最大的 \(j\)​ 作为 \(i\)​ 的重儿子然后取链顶权值之和,但是这样 \(1\)​ 不一定满足要求,因为此时只有一个点权值 \(\ge a_1\)​,此时我们还要再取一个点将其权值改为 \(a_1\)​。这个其实也好办,设 \(mx\)​ 为 \(1\)​ 的轻儿子中权值最大的,那么我们只需将 \(1\)​ 的权值为 \(mx\)​ 的轻儿子所在的那条链的权值改为 \(a_1\)​ 即可,答案额外加上 \(a_1-mx\)​。

考虑更一般的情形。注意到对于一个点 \(u\)​ 而言,如果以 \(u\)​ 为根时,\(u\)​ 的两个子树内都存在权值 \(\ge a_u\) 的点,那么如果其他点都符合要求,这个点也一定符合要求,我们定义这样的点为“无用点”。那么考虑以有用点中权值最大的\(R\) 为根,那么所有有用点必然满足“祖先 \(\ge\) 当前节点权值”的性质,那么我们考虑先以 \(R\) 为根进行一遍 DFS,然后令每个点的权值对其每个儿子的权值取 \(\max\),然后再跑一遍上面的做法即可。

赛后才发现我是 sb, 只要以全局权值最大的点为根即可。

G

首先特判 \(n=2\) 的情况。

注意到样例给的 \(n\) 很小,这意味着当 \(n\) 比较大时可能会有一些不错的性质待挖掘,因此考虑先来手玩一下 \(n=4\) 的情况。发现不论你怎么选,最终得到的四个数都是 \(2\) 的整数次幂,因此我们做出猜想:最终的得到的 \(n\) 个数都是 \(\ge n\) 且最小的 \(2\) 的整数次幂 \(N\)

这是为什么呢?可以发现,如果一次操作后,\(x,y\) 都包含同一个奇因子,那么操作前这两个数也包含这个奇因子,也就是说,如果最后得到的数不是 \(2\) 的幂,那么考虑取出这个数的一个奇因子 \(f\),可以得到最一开始的 \(n\) 个数都是 \(f\) 的倍数,当 \(f>1\) 时显然不成立。

接下来考虑构造。我们将此题分成两个部分:先构造出若干个 \(2\) 的整数次幂,再将这若干个 \(2\) 的整数次幂都变为 \(N\)。对于前一部分,我们考虑递归函数 solve(n, k) 表示将 \(2^k,2·2^k,3·2^k,\cdots,n·2^k\) 都变为 \(2\) 的整数次幂的过程,如果 \(n\)\(2\) 的整数次幂那么递归 solve(n - 1, k),否则我们找出 \(\le n\) 且最大的 \(2\) 的整数次幂 \(n_0\),对于 \(i\in[1,n-n_0]\),依次将 \((n_0+i)·2^k,(n_0-i)·2^k\) 配对,这样可以得到 \(2^{k+1}\sim(n-n_0)·2^{k+1}\),而剩余的数恰好是 \(2^k\sim(2n_0-n-1)·2^k\),递归下去即可。

接下来考虑问题的第二部分,由 \(n\)​ 个 \(2\)​ 的幂构造出 \(n\)​ 个 \(N\)​,考虑从小到大枚举每个 \(2\)​ 的幂 \(2^k\)​,如果有超过两个 \(2^k\)​ 就对它们进行一次操作得到 \(2^{k+1}\)​ 和 \(0\)​,否则如果此时序列中有 \(0\)​,就进行一遍 \(2^k\)​ 与 \(0\)​ 得到两个 \(2^k\)​ 再操作,否则就对 \(2^k\)​ 与 \(2^{k+1}\) 进行一次操作得到 \(3·2^k\)\(2^k\),再进行一次操作可以得到 \(2^{k+1}\)\(2^{k+2}\)

题目允许操作次数的上界是 \(20n\),但是此算法在实际表现中操作次数大约在 \(3n\) 左右,有没有好鸽鸽教教我证一下这个算法操作次数的上界啊/dk

H

开始搬官方题解(

首先发现一个性质:如果一个 \(p_i\)​ 被选择,那么它后面的所有小于它的数都会被选,证明可以见官方题解。

假设我们选出的下标集合为 \(S\),那么考虑如何用一个比较简洁的式子表示出将 \(S\) 移到序列开头后逆序对的数量。记 \(d_i\) 表示只把 \(d\) 移到序列开头后,序列逆序对数的变化量,即 \(\sum\limits_{j<i}[p_j<p_i]-\sum\limits_{j<i}[p_j>p_i]\)\(s_i\) 表示 \(i\) 后面比 \(i\) 小的数的个数,即 \(\sum\limits_{j>i}[p_j<p_i]\)\(X\) 表示原序列的逆序对数,那么对于一组最优下标集合 \(S\),将 \(S\) 中元素移到序列开头后逆序对数的数量就是

\[X+\sum\limits_{x\in S}(d_x+2s_x)-\dfrac{|S|(|S|-1)}{2} \]

稍微解释一下这个式子:我们记 \(S\) 中的元素为黑点,不在 \(S\) 中的元素为白点,那么发现对于一组逆序对 \(x,y\),它们的颜色有三种可能:

  • \(x,y\) 都是白点,那么这样的逆序对的贡献在 \(X\) 中已经被计算了。
  • \(x\) 是黑点,\(y\) 是白点,那么这样的逆序对的贡献在 \(d_x\) 的 delta 中已经被计算了,\(x\) 是白点,\(y\) 是黑点的情况也同理。
  • \(x,y\) 都是黑点,这里我们分两种情况:
    • 如果 \(x,y\) 在原序列中是一对顺序对(即 \(x<y,p_x<p_y\)),那么它对 \(X\) 的贡献为 \(0\),对 \(d_x\) 的贡献为 \(0\),但对 \(d_y\) 却有 \(1\) 的贡献,实际上这对数在最终序列中不是逆序对,因此我们要把这对 \(x,y\) 的贡献减掉。
    • 如果 \(x,y\)​​ 在原序列中是一对逆序对(即 \(x<y,p_x>p_y\)​​),那么它对 \(X\)​​ 的贡献为 \(1\)​​,对 \(d_x\)​​ 的贡献为 \(0\)​​,对 \(d_y\)​​ 的贡献为 \(-1\)​​,三者之和为 \(0\),但实际上这对数在最终序列中是逆序对,会对答案产生 \(1\) 的贡献,因此我们要把这对 \(x,y\)​​ 的贡献重新加上。

也就是说,将 \(S\)​ 中元素移到序列开头后,逆序对数的数量可以写作 \(X+\sum\limits_{x\in S}+\sum\limits_{x,y\in S,x<y}[p_x>p_y]-\sum\limits_{x,y\in S,x<y}[p_x<p_y]\)​。而由于 \(S\)​ 是一组最优下标集合,因此对于一个数 \(x\in S\),所有 \(y>x,p_y<p_x\)\(y\)​ 也都属于集合 \(S\),因此 \(S\) 中逆序对数量就是 \(\sum\limits_{x\in S}s_x\),顺序对数量也就是 \(\dfrac{|S|(|S|-1)}{2}-\sum\limits_{x\in S}s_x\),稍微变个形即可得到上式。

推出这个式子后,此题就变得容易许多了,记 \(c_i=d_i+2s_i\),对于一个固定的 \(k\),贪心地取最小的 \(k\)\(c_i\) 累加入答案即可。你可能会担心选出来的这些下标集合不是最优下标集合,导致上面答案的式子不成立,事实上你的担心是多余的,因为对于一组 \(i<j,p_i>p_j\)\((i,j)\),显然有 \(c_j<c_i\),因此在选择一个 \(c_i\) 之前,所有 \(i<j,p_i>p_j\)\(c_j\) 也会被选。

时间复杂度 \(n\log n\)

第一次在 glbr 中做出价值 4000 points 的题目,也是第一次在 glbr 中打出 10000 points 以上的成绩,算是个小小的纪念吧。也希望以后能一直保持这场比赛的状态,再接再厉。

posted @ 2022-02-14 12:42  tzc_wk  阅读(132)  评论(0编辑  收藏  举报