一类匹配问题的移位技巧(The SHIFT Trick)
引子:(广义错排问题)有$n$个班级,第$i$个班有$a_i$人,每人都写一张贺卡送给另一个人,问是否存在一个分配方案,使得
- 每个人都获得恰好一张贺卡,并且与这张贺卡的作者来自不同班级。
当$a_i = 1$时,该问题退化成【错排】问题。
定理:令$m = \sum_{i} a_i$表示总人数,则存在一个合法的分配方案当且仅当
$$ \max_i \{ a_i \} \leq \frac m 2. $$
证明:
- 先证充分性。若存在$a_i > m/2$,即有一个班的人数超过总人数的一半,则由鸽笼原理,这个班中至少有一个人收到来自这个班的贺卡;从而不存在一个合法的分配方案。
- 再证必要性。若对所有$i$,都有$a_i \leq m/2$,则将$m$个人按照班级顺序排成一列$b_0, b_1, \dots, b_{m-1}$,其中同一个班级的人组成连续的一段,考虑对每个$0 \leq i < m$,将$b_i$的贺卡分配给$b_{(i+\lfloor m/2 \rfloor) \bmod m}$,为一个合法的分配方案。因为,$b_i$与$b_{(i+\lfloor m/2 \rfloor) \bmod m}$必不在同一个班,不然这个班的人数将超过$m/2$。
在以上证明中,我们把$b_i$做了一个长度为$\lfloor m/2 \rfloor$的移位。我们姑且将其称作【移位技巧】(the SHIFT trick)。在一些题目中,往往要求给出具体分配方案,这时移位技巧的优势就体现出来了,因为只需要极短的代码。我才不会说我无数次因为给出方案太麻烦导致知道怎么却到最后也没做出来
给定一个长度为$n(n \leq 100,000)$的数组$b_1, b_2, \dots, b_n (1 \leq b_i \leq n+1)$,以及参数$x, y (0 \leq x \leq y \leq n)$,要求构造一个数组$a_1, a_2, \dots, a_n (1 \leq a_i \leq n)$,使得
- $a$和$b$中恰好有$y$个元素相同;
- 恰好有$x$个下标$i_1, i_2, \dots, i_x$,使得$b_{i_s} = a_{i_s}$。
解:先考虑一个简化版问题$x = 0$的情形,即要求$a$中有$y$个元素与$b$中相同,但要求【错排】。当$y = n$时,退化成【广义错排问题】,即要求出现最多的元素的出现次数$\leq n/2$。对于$y < n$的情形,我们仍然对数组$b$应用一次【移位技巧】得到$c_1, c_2, \dots, c_n$,设$b$与$c$有相同元素的下标(称为【冲突】下标)个数为$k$,设$f$表示$b$中出现最多的元素个数,则
$$ k = \max \left\{ 2f-n, 0 \right\}. $$
(感谢MicroMaker指正。)
为解决这$k$个【冲突】下标,我们注意到,一定存在一个值$1 \leq e \leq n+1$,其不在$b$中出现;从而我们可以把【冲突】下标对应$c$的元素设为$e$。而我们必须恰好将$(n-y)$个$e$设为$c$的元素,于是必须满足
$$ k = \max \left\{ 2f-n, 0 \right\} \leq n-y. $$
(若不满足则无解。)对于多出来仍未设置的$e$,其实是可以随意设置的。
现在我们来考虑一般情况下$x \neq 0$的问题。我们假设已经选出$x$个下标,将$b$与$a$对应的部分设为相同元素。根据之前的分析,对于剩下的$x$个下标以外的下标,我们希望【冲突】下标个数$k$尽可能小;于是我们的策略是贪心选取$x$次,每次选择当前出现次数最多的元素的一个下标。至此,问题得到了完美解决。
CodeForces 1280C. Jeremy Bearimy
CodeForces 1387B2. Village (Maximum)
给定$n$个节点的树,每个节点上有一个人,这$n$个人在玩“大风吹”(即每个人要去到与自己当前所在节点不同的节点)。要求最大化所有人移动距离之和。
解:对于树上的每一条边$e$,边权为$w_e$,设这条边将树分成大小为$x_e$和$y_e$的两个部分,则至多有$2\min\{x_e, y_e\}$个人可以经过这条边。从而得到最大距离和的上界
$$ \sum_e 2 w_e \min\{ x_e, y_e \}. $$
这个上界实际上是可以达到的。我们考虑这棵树的【重心】$G$,即若以$G$为根建树,则$G$的儿子节点对应的子树大小均$\leq n/2$。我们可以把$G$的每个儿子的子树看作是一个【班】,特别地,$G$本身也看作是一个班(只有$G$一个人),由于每个班的人数都$\leq n/2$,故可应用【广义错排问题】。在错排方案中,每个节点都对应到与他不同子树的节点,因此每条边被经过的次数都能达到上界$2\min\{x_e, y_e\}$。
我们应用【广义错排问题】给出了具体的分配方案,但需要先求出树的重心。其实有更简洁的做法:直接求出树的DFS序(以任意节点为根),在DFS序上直接应用【移位技巧】就能得到一个最优方案了。
原因是假若我们选择任意一个重心$G$,两个在DFS序中距离$\lfloor n/2 \rfloor$的节点一定不会同时在$G$的某个儿子对应的子树中(不然,这个子树的大小就超过$n/2$了,与$G$是重心矛盾)。
加强版:若要求这$n$个人的移动的形成一个轮换,即$p_1$去到$p_2$,$p_2$去到$p_3$,...,$p_{n-1}$去到$p_{n}$,$p_n$去到$p_1$。仍然最大化所有人移动距离和。
这同样也能达到上述最大上界。我们先考虑一个简化版问题。
问题:(广义错排问题加强版)设有$n$个班级,每个班级有$a_i$人,要求将所有人排成一个环,使得没有相同班级的人相邻。
定理:以上问题所有人能排成一个环,当且仅当,$\max_i \{ a_i \} \leq m/2$,其中$m = \sum_i a_i$。
我们可以看到,【广义错排问题】是以上问题的一个简化版本。
证明:若$a_i > m/2$,则显然不行。若对所有班级$i$,$a_i \leq m/2$,我们用归纳法证明所有人能排成一个环。
按总人数$m$归纳。
当总人数$m = 2$时,只有一种情形,两个班,且$a_1 = a_2 = 1$,这个情况显然所有人能排成一个环。
当总人数$m = 3$时,也只有一种情形,三个班,且$a_1 = a_2 = a_3 = 1$,这个情况显然所有人能排成一个环。
对$k \geq 4$,我们设$2 \leq m < k$时,命题成立。我们不妨设当前有$n$个班,且$n/2 \geq a_1 \geq a_2 \geq \dots \geq a_n$。我们从第一个班与第二个班中分别抽出一个人,则第一个班剩下$a_1-1 \leq (m-1)/2$人,第二个班剩下$a_2-1 \leq (m-1)/2$人,其余班$i \geq 3$的人数仍为$a_i$。则剩下的$m-2$个人应用归纳假设,可以排成一个环$\pi$。我们从环$\pi$中任选两个相邻的人,设他们分别来自$x$和$y$两个班$x \neq y$,则必有($x \neq 1$且$y \neq 2$)或者($x \neq 2$且$y \neq 1$),不妨设是前者,则我们把之前取出的第一个班和第二个班的人插至他们中间,形成$x \to 1 \to 2 \to y$。于是我们构造出了一个$m$个人的环。故$m = k$时命题成立。
我们回到原问题。这次我们再次选取重心$G$,$G$的每个儿子节点对应的子树看作是一个【班】,$G$自己也看作是一个【班】(这个班只有$G$一个人),根据【广义错排问题加强版】,我们可以得到所有节点的一个轮换。从而移动距离和达到上界。
AtCoder AGC 018 D. Tree and Hamilton Path
给定$n$个节点的树,要求构造一个排列$p_1, p_2, \dots, p_n$,使得从$p_1$走到$p_2$,再从$p_2$走到$p_3$,...,最后从$p_{n-1}$走到$p_n$的距离之和最大。
解:根据之前的论断,我们同样得到最大距离和的上界
$$ S = \sum_e 2 w_e \min\{ x_e, y_e \}. $$
但很不幸,这次达不到上界了,但应该仍然与重心有关。任何一棵树,都是以下两种情形之一:
- 存在一条边$e$,将树分成大小相等的两半,即$x_e = y_e = n/2$(暗含$n$是偶数)。此时,我们至多经过这条边$n-1$次,从而最大距离和的上界缩小为$S - w_e$。
这个上界是能达到的。考虑这条边分成的两个部分的节点分别是$x_1, x_2, \dots, x_{n/2}$与$y_1, y_2, \dots, y_{n/2}$,考虑按以下顺序走
$$ x_1 \to y_1 \to x_2 \to y_2 \to \dots \to x_{n/2} \to y_{n/2}. $$
按这个顺序即能达到最远距离和。 - 存在唯一一个重心节点$G$,且$G$的儿子对应的子树大小均$< n/2$。设$G$的儿子节点依次为$e_1, e_2, \dots, e_k$(我们也同样用$e_i$表示$G$与节点$e_i$之间的连边,并用$\text{size}(e_i)$表示以节点$e_i$为根的子树大小,则$\text{size}(e_i) < n/2$)。对$G$的每个儿子节点$e_i$,边$e_i$至多经过$2 \text{size}(e_i)$次,并且要达到这个次数,起始点必须不能在$e_i$子树内部;但我们无法对所有$e_i$都满足这个条件,所以至少有一条边$e_i$只能经过$2 \text{size}(e_i) - 1$次。因此,最大距离和的上界缩小为$S - \min_i \{ w_{e_i} \}$。
这个上界是能达到的。我们应用【广义错排问题加强版】,把除了$G$以外的所有节点排成一个环,要求同一个子树的节点不相邻。设$e_{i^*}$是权值最小的边,我们从节点$G$出发,然后走到$e_{i^*}$,而剩下的走法绕环一周即可。如此,则达到上界。
CodeForces 1396E. Distance Matching
见这里。