A
考虑存在 ai=100 的情况,那么对于所有的 0≤k<100n(其中 k=100n 的情况是平凡的)总可以通过令 xi=kmod100,剩下随便选 ⌊k/100⌋ 个 j=i,令 xj=aj,就是一个解。
如果不存在 ai=100 的情况,那么 k=1 就凑不出来。
复杂度 O(n)。
B
由于允许操作的区间长度是奇数,不难看出奇数位置的元素只能在奇数位置之间流动,偶数同理。
并且,如果 p≡q(mod2),我们总可以通过一次交换把 p,q 互换。
那么我们只需关心 xi 的奇偶性。令 s0 为子序列 a2,a4,a6,…,s1 为子序列 a1,a3,a5,…。
令 ti=ximod2,那么每一次操作我们必须在 sti 中标记一个元素,记答案初始为所有元素之和。
- 如果 sti 的元素都没有被标记过,显然我们会标记最大的元素,令答案减去这个元素;
- 如果 sti 存在被标记过的元素,那么如果存在没被标记过的正整数,就标记最大的正整数,这样答案减去的最多;否则任意标记一个已经被标记过的元素,答案保持不变。
复杂度主要在于排序,为 O(nlogn)。
C
首先不难看出这是一个 dp,关键在于我们不知道所有子区间的中位数是谁。
假设知道这个中位数是 x,那么设 dpi 表示 i 结尾的所有合法划分中,最多的子区间个数,转移为 dpi=max0≤j<i{dpj+1},其中 aj+1∼ai 的中位数是 x,并且 i−j 为奇数。
给定的 n 总是奇数,而这个 dp 似乎并不依赖于 n 的奇偶性,这就意味着一定存在某种性质。
假设每一个子区间的中位数都是 x,由于子区间的长度为奇数,子区间的长度之和 n 也为奇数,那么一定有奇数个子区间。
既然一共有奇数个子区间,那么这些子区间并起来的中位数就一定等于 x,这个结论简单画图即可得出。
也就是说 x 是可以直接求出来的,那么复杂度就是 dp 转移的复杂度,为 O(n2)。
注意,这个转移并不一定是求出 aj+1∼ai 的中位数,因为动态求中位数一般来讲会用对顶堆,复杂度会多一个 log;而这里我们是判断中位数是否为 x,只需要记一下比 x 大和比 x 小的元素个数,然后它们都 ≤(i−j−1)/2 就是中位数为 x 的充要条件。
D
令 Si=∑k=inak,那么一个逆序对 (i,j) 的贡献就是 Si−Sj。
对于每一个 pi,我们都希望所有 j>i 且 Si−Sj>0 的 j 都满足 pi>pj;所有 j>i 且 Si−Sj<0 的 j 都满足 pi<pj。
如果能做到这一点,显然此时 ∑i<j,pi>pjSi−Sj 就会取到最大值,因为每一个位置 i 的 Si 是固定的。
事实上也确实可以做到,只需要令 Si 和 pi 的相对大小保持一致即可,也就是说,我们给 (Si,i) 这个二元组按照字典序排序,然后按照排序后的位置从 1∼n 给 pi 赋值即可。
这样的话,每一个位置 i,对于 j>i,总是满足 Sj<Si 时有 pj<pi;Sj>Si 时有 pj>pi。
复杂度 O(nlogn)。
E
没想到这个交互我能做出来,下面令 I(x) 表示询问 I x,Q(x) 表示询问 Q x。
由于 c=0,那么这三种操作中最特殊的 x 必然是 0,因为 k=1 时 f(0)=0,k=1 时 f(0)=c。
因此第一步我们令 a=0,然后询问 I(0) 区分出 k=1 还是 k=2,3。
如果 k=1,此时 S={0},我们只需要询问 I(20),I(21),…,I(2n−1) 即可。由于 f(2i) 不是 0 就是 2i,所以根据 I 的返回值我们总能正确判断出 c 的第 i 位是 0 还是 1。
如果 k=2,3,此时 S={0,c},我们询问 I(2n−1)。
-
如果 S 不变,说明 c=2n−1,此时我们只需询问 I(1) 即可区分出 k=2 还是 k=3。
-
如果 S 变了,说明 c=2n−1,但是还是有两种情况:
- 若 k=2,此时 S={0,c,2n−1};
- 若 k=3,此时 S={0,c,¬c},其中 ¬c 表示 c 的 n 个二进制位按位取反。
由于 c=2n−1 且 c=0,所以无论是 c 还是 ¬c 都一定是既有 0 又有 1,所以 c,¬c<2n−1,因此询问 Q(2n−1) 就可以区分出 k=2 还是 k=3。
-
若 k=2,我们通过二分区间 l=1,r=2n−2 就可以找到 c。
-
若 k=3,我们并不知道 c 和 ¬c 哪一个大。
假设我们可以二分找到其中一个值,此时我们仍需要判断得到的是哪一个。
假设我们二分出的是 r,那么 f(c)=0∈S,f(¬c)=2n−1∈S。所以询问 I(r) 即可区分出 c 和 ¬c。
但是这里还有一个问题,不算二分次数,我们已经用掉了 4 次询问,然而题目要求我们使用 n+3 次询问,如何解决?
由于 c 和 ¬c 一定有一个人最高位为 1,所以我们二分区间设置 l=2n−1,r=2n−1 即可少一次二分。
复杂度 O(n)。
F
令 1∼n 的图为 G,1∼q 的图为 GQ,那么要做的就是在 GQ 这个完全图上求最小生成树,其中边 (i,j) 的权为 dis(ci,cj)。
考虑 Gx 为 G 删掉边权为 x 的所有边后构成的图,那么 dis(u,v)=min{x∣(u,v) is connected in Gx}。
反过来看,如果我们可以从小到大遍历 x=0∼m+1,并且把 Gx 中所有连通块对应到 GQ 中的点也连通起来,就等价于执行 Kruskal 算法。
问题是朴素遍历是 O(mn2) 的,显然无法通过本题。
观察 Gx 为删除边权为 x 的所有边,删除并且维护连通性并不简单,但是我们可以用线段树分治,将删除一条边,变为一条边只在某个区间中出现。
那么考虑暴力遍历 Gx 中所有连通分量的操作,就等价于我们在 Gx 对应的并查集合并的过程中,把 Gx 并查集对应的 GQ 中对应的点也合并起来。
在实现上,我们需要将 Gx 对应的并查集节点 u 添加一个 ru 属性,表示 Gx 的点 u 对应在 GQ 的并查集的点是谁,如果不存在则为 0。在合并 Gx 对应并查集的过程中,我们应当同时合并 GQ 对应的并查集。注意特殊处理 r=0 的情况。
这里可以看作 ru 是一个等价类的集合,只不过只存储了这个等价类的某一个元素,那这里的处理就比较显然了,只要从集合合并的角度去理解即可。
将 n,m,q 视作同阶,复杂度 O(nlog2n),其中一个 log 是线段树分治,另一个 log 是可撤销并查集。