[CF2188C] Restricted Sorting
这道题目我疑似是假做法,就直接搬运官方题解了,补充了一些证明。
考虑 a 排序后的数组是 b,那么对于 ai=bi 的位置 i 我们不需要管它,于是我们找到 ai=bi 的位置,并且记录下来最大值和最小值 mx,mn。
这里一定有 mn=mx,否则,这些元素是同一个值,并且除了这些元素之外的元素都已经排序完成了,那么比它大的元素在正确的位置,比它小的元素同理,那么这一些元素又是相等的,它们必然在正确的位置。
然后,对于所有 ai=bi 的位置,如果 mx−ai<k 且 ai−mn<k,那么 ai 与任意元素都不可换,此时的 k 是非法的。
所以,对于所有 ai=bi 的位置,必须有 mx−ai≥k 或 ai−mn≥k 成立,此时我们可以证明对于任意的 i,j 满足 ai=bi,aj=bj 的位置,它们都是可以交换的:
- 如果 ai,aj 是 mx 和 mn,它们一定可换。
- 否则,ai,aj 和 mx,mn 其中之一都可换,直接通过 mx 或者 mn 交换即可。容易看出,如果 ai,aj 其中之一是 mx,mn 另一个不是的话,是落在这一个条件里的。
- 否则,不妨设 ai 与 mx 可换,aj 与 mn 可换,那么它们分别交换之后交换 mx,mn 再交换回去,就能通过 mx,mn 交换 ai,aj。
所以这是一个充要条件。
[CF2188D] Shortest Statement Ever
我没看懂官方题解,这里说一下我怎么做的,设 B 是 x,y 的二进制位数量。
分类讨论四种情况,0≤p≤x,p>x 与 0≤q≤y,q>y 组合一下,有 2×2=4 种情况,又因为有两种情况是互相对称的,所以只需要讨论三种情况:
-
当 0≤p≤x,0≤q≤y 时,∣x−p∣+∣y−q∣=x+y−(p+q),我们只需要求出 p+q 的最大值。
又因为 p∩q=∅,所以 p+q=p⊕q。
根据贪心的思路,我们从高向低枚举每一个位,设 x,y 这一位上分别是 X,Y。
- 如果 X=Y=0,那么只能填 0;
- 如果 X=0,Y=1,我们让 p 的这一位填 1,给 p+q 这一位贡献上了一个 1;
- 如果 X=1,Y=0,同上;
- 如果 X=Y=1,那么给 p 填一个 1,给 q 剩下的所有位都填 1,这样后续的所有位都是 1。
根据二进制的性质,我们尽量填高位,并且让尽量填高位的同时后面能填的位全部填上了(遇到情况 4 之前能填则填,遇到情况 4 之后所有位都填),所以这就是 p+q 能取到的最大值。
-
当 p>x,q>y 时,∣x−p∣+∣y−q∣=p+q−x−y,我们需要让 p+q 最小。
我们可以 O(B) 枚举 p 从哪一位开始比 x 大,那么从这一位往后全是 0 可以让 p 最小的同时给 q 留出最多的操作空间,此时再 O(B) 枚举 q 从哪一位开始比 y 大,注意满足 p∩q=∅。
-
当 p>x,q≤y 时,∣x−p∣+∣y−q∣=p−q−x+y,我们需要让 p−q 最小。
同上,也是 O(B2) 可以枚举出来的。
如果按照这个思路来,本题目较为扎实地考察了贪心的思想,也就是有些时候多个限制条件是可以被构造出来的某种特殊情况(即上面的让后面全是 0 这种操作)同时满足的。
[CF2188E] Jerry and Tom
本题的重要结论是,如果 i 有多条出边,无论是 Jerry 还是 Tom,都会走对应节点最大的一条。
设 ai 是 i 的所有出边中对应节点最大的那个节点,那么 i 到达 n 的路径必然经过 ai。
证明:假设 i 到 n 的路径上不经过 ai,说明 i 的下一步 j 不是 ai,又因为 ai 是 i 的所有出边中对应节点最大的节点,那么 j<ai。设 j 的下一步是 k(=ai,k>j),那么:
- 如果 k>ai,违背题目条件。
- 如果 k<ai,令 j←k,重复上述流程,必定再有限步内违背题目条件。
故命题得证,那我们可以构建一颗树,节点 i 的父节点是 ai,根是 n,每一个节点的深度是 di
根据我们上面的论述,i 到 n 的所有路径(不一定要走树边)都会经过 ai,那么 i∼n 的任意一条路径都会包含这棵树上 i∼n 路径上的所有节点。
假设 Jerry 在 x,Tom 在 y,并且 lca(x,y)=u,那么 Jerry 不会被抓当且仅当 dx<dy。
- 当 dx<dy 时,只要 Jerry 一直沿树边走,Tom 最快的速度也就是沿着树边走,是没有办法抓到 Jerry 的。
- 当 dx≥dy 时,Tom 以最快速度走到 u 会比 Jerry 更先到达 u(同时到达也视为更快),那么 Jerry 是一定会被抓的。
并且,我们可以知道,如果 Tom 未到达 u,是无法抓住 Jerry 的;如果 Tom 到达了 u,它没有必要继续往上走;在到达 u 之前的所有路径中,走树边是最快的。所以说 f(x,y)=dy−du。
于是我们计算的值就有了:∑1≤x,y≤n,x=y,dx≥dydy−dlca(x,y)。
因为原本的 (x,y) 对要求了 x=y,于是要么 x>y,要么 x<y,我们可以只枚举 x<y 的 (x,y) 对,然后加上 (x,y) 和 (y,x) 两个对的贡献。
于是转化成了 ∑1≤x<y≤n(dx−dlca(x,y))[dx≤dy]+(dy−dlca(x,y))[dx≥dy]。
我们知道 dx 和 dy 也只有三种关系,大于、小于和等于。
如果 dx=dy,那么一个 (x,y) 对会产生两个贡献,否则只会产生一个贡献。我们不妨都贡献一次,然后把满足 dx=dy 的 (x,y) 找出来再贡献一次,于是就转换成了 (∑1≤x<y≤nmin(dx,dy))−(∑1≤x<y≤ndlca(x,y))+(∑1≤x<y≤n,dx=dydy−dlca(x,y))。
对于第一部分,我们只需要给 d 数组排序之后就容易得出,注意后面我们还要用 d 数组,所以实际上这是最后处理的;
对于第二部分,我们可以在第一遍 DFS 预处理时枚举每一个点作为 lca(x,y) 然后统计满足条件的 (x,y) 对;
对于第三部分,可以用 DSU On Tree 的思路,开一个关于 d 的计数数组,枚举轻边下的子树中所有节点即可。
题解说了存在线性做法,但是我不会。
[CF2188F] Cool Problem
既然要求和,那么我们应当先求出 ci 某种意义上的通项公式,硬做的话显然有一些正负号相互抵消了,状态量太大。
问题是 ci 和 ci−1 之间的关系式的系数不一定一样,我们需要用某种方式给它们统一,所以设 vi 满足这样的关系:
- v0=1;
- 若 ri=0,则 vi=vi−1;
- 若 ri=1,则 vi=−vi−1。
于是,我们给 ci 和 ci−1 的递推式就满足:
- 若 ri=0,则 civi=xvi−1+ci−1vi−1;
- 若 ri=1,则 civi=−yvi−1+ci−1vi−1。
既然我们的 vi 已经分类讨论了,那么就不要再让 civi−ci−1vi−1 分类讨论了,我们希望利用这个已经讨论后的量。
具体地说,我们希望一个关于 vi,vi−1 的统一的式子 F 和 civi−ci−1vi−1 的值相等,即:
- 若 vi=vi−1,则 F=xvi−1;
- 若 vi=−vi−1,则 F=−yvi−1。
可以待定系数法构造出 F=2x+yvi+2x−yvi−1 符合条件,于是我们就有:
civi−ci−1vi−1civi−c0v0=2x+yvi+2x−yvi−1=2x+yj=1∑ivj+2x−yj=0∑i−1vj
设 Si=∑j=1ivj,那么我们有 civi=2x+ySi+2x−ySi−1+2x−y,注意 v0=1。
又因为 vi=±1,所以 ci=civi2,于是我们可以继续写出 f(r) 的表达式:
f(r)=i=1∑ncivi2=i=1∑n2x+ySivi+2x−ySi−1vi+2x−yvi=2x−ySn+i=1∑n2x+ySi2−2x+ySiSi−1+2x−ySiSi−1−2x−ySi−12=2x−ySn+i=1∑n2x(Si2−Si−12)+2y(Si2+Si−12−2SiSi−1)=2xSn2+(x−y)Sn+ny
于是 f(r) 可以被 Sn 唯一确定。Sn 的值域只是 [−n,n],我们可以动态规划求出 Sn 的所有可能取值。
具体地说,令 dp1 表示当前 vi=1 时 Sn 的所有取值构成的集合,dp2 表示当前 vi=0 时 Sn 的所有取值构成的集合,然后根据 ri 的不同在 dp1,dp2 相互进行转移即可,用 bitset 优化可以做到 O(n2/ω)。