复习 #2:构造题的思考方式

· · 个人记录

很多之间很熟练的技巧现在都不记得了。

有的人上上周都还不会写最短路,哈哈。

构造题并没有结论或模板之类的东西,只能采用例题来进行说明

归纳法

最常用的构造方法之一,通过提出构造对象的某个特殊的单元,解决规模更小的问题,然后将提出的单元合并回去得到原问题的解。

给定一有向图,将点染成黑白两种颜色,要求黑色点之间不能有连边,任意白点到最近黑点的距离 \leq 2

考虑归纳构造,任取点 u,将 uu 指向的所有节点删去,对新得到的点集构造答案。然后考虑:得到的点集中,是否存在一个点,满足它指向 u, 且它的颜色为黑色。如果没有,可以把 u 染成黑色,否则将 u 染成白色。

可以检验,加入 u 以及它指向的节点后,依然满足题目限制。

CF1517C:给定一个 nn 列的下三角区域,主对角线上已经填了 1 \sim n 的一个排列,你需要将其他格子也填上 [1,n] 之间的数字,满足数字 i 出现次数恰好为 i,且所有出现位置形成了一个联通块。

注意到数 1 的出现位置已经确定了,将对角线中 1 上方的位置的下方一个格子填上和它相同的数,1 下方的位置的左侧一个格子填上和它相同的数。这样,我们将问题归纳为了大小为 n - 1 的子问题。

NOIP2020 T3 移球游戏

根据题目条件,我们知道这样的一个问题是可以解决的:有 n +1 根柱子和 n 种颜色,前 n 根柱子上恰有 m 个球,每种颜色的球恰有 m 个,最后一根柱子是空的。目标是使得所有柱子上的球颜色相同。

考虑利用最后一根柱子将问题归纳为大小为 n - 1 的子问题(也就是,将使得某一根柱子上的球颜色相同,然后就可以删去这根柱子)。

大致的做法是,考虑把所有颜色 c 堆到空柱子上。称一开始的空柱子为待命柱。对于柱子 i(称为当前柱),若它上面有 x 个颜色为 c 的球,我们随便从另一个柱子(称为临时柱)上取 x 个球放到待命柱顶部,然后取出柱子 i 的所有球,若它是颜色 c,则把它放到临时柱顶部,否则放到待命柱顶部(可以发现这样恰好可以放完)。然后把待命柱顶部的所有非颜色 c 的球放到当前柱中,再把临时柱顶端所有颜色 c 的球放到待命柱顶部。复杂度 O(n^2m),进行一定的常数优化即可通过。

对限制条件的分析

分析题目所给出的限制条件,并尝试构造以满足题目要求。

CF1383D Rearrange

考虑构造一矩阵满足最大值的限制:

CF1510J Japanese Game

考虑一个 profile 的 mask 是什么形式。

定义一个 profile 的自由度 f:从左往右贪心地摆完,右边会剩下多大的空间。(即,n - \sum_{i=1}^k L_i - (k - 1)

我们考虑某一段,把它左边的段尽可能向左放,它右边的段尽可能向右放,它会有一个可以移动的区间,而有一部分格子是它无论如何移动都会覆盖到的,这一部分就是 mask。

形式化地,从左往右贪心地把每段摆在尽可能左的位置,若它的长度是 L,那么它右边 L - f 的长度是 mask。

若我们已知 f,考虑构造一个 profile。我们是知道所有长度 >f 的段(会产生 mask)的长度的。我们只需要用一些长度 \leq f 的段来把它们对齐到合适的位置。

首先如果两段之间的空隙必须 \geq f。如果是 f + 1 那么当然不用填,如果是 f + 2,可以发现是没有解的。否则,如果 f > 2,你可以用 12 填起来。

根据上述条件,找出一个合法的 f 构造即可。注意特殊处理 f = 0f = 1

1494F Delete The Edges

需要讨论的情况较多,因此略去分类讨论的过程。

注意到操作之后能消除的边一定是一个菊花图。枚举菊花心 x,删去一些从它到其它点的边,一定要剩下一条从它开始的欧拉路径。

注意到删去连向偶度点的边是不优的,不妨先把到奇点的边删了,这样一定能最小化奇数点的个数。

如果存在边(非孤立点)的连通块个数 =1,并且没有奇数点或者奇数点只有 2 个且包含 x,那可以直接构造答案。

如果存在边的连通块数 = 2,一定要连回去一条边(而且你知道这条边是什么)。此时若有奇数点,讨论一下发现一定不合法。否则连那条边,可以直接构造答案。

对于其他情况,讨论知一定不合法。

[USACO21FEB] Minimizing Edges P

O_u,E_u$ 分别为走过奇数/偶数步的最短路,可以发现,要求任取 $u$, $O_u = O'_u, E_u = E'_u

A_u = \min \{O_u,E_u\}B_u = \max \{O_u,E_u\}。拉一棵 bfs 树出来,显然节点 u 的深度等于 A_u

最短路树的限制是很强的,非树边只能连接相邻两层。考虑怎样满足 AB 的限制。A 的限制容易处理,每个点一定要向前一层连一条边。接下来主要考虑如何构造图满足 B 的限制。

B_u = A_u + 1 的点为关键点。若一个点 u 不是关键点,则一定向一个满足 B_v = B_u - 1 的点 v 连边。否则,它可以由上述方式满足限制,或者由一条连接同一层两个关键点的边来满足限制。

考虑按层依次构造答案,对于一层的每个点 u ,若:前一层存在尚未满足限制的点 v 使得 B_v = B_u + 1,则从 uv 连边,满足 v 的限制。否则,若存在点 v 使得 B_u = B_v + 1,则向 v 连边,满足 u 的限制。否则随意连一条合法的边。(为什么正确?对答案贡献均为 1,而之前层只能由当前层匹配,当前层还可能由后面消除,可行决策集合严格包含)

做完之后,对每一层考虑尚未满足限制的点,其中关键点有 c_1 个,非关键点有 c_2 个,一条边可以满足两个关键点的合法性(也可以是一个,连一个自环),而对于非关键点,只能向前一层/后一层连一条边来保证合法(因为是由一个存在的图构造出来的,一定可以这样做)。增加的边数为 \lceil \frac{c_1}{2} \rceil + c2

给定 a,b,c,M,求一组 x,y,z 满足 0 < x,y,z < Mx^a + y^b \equiv z^c \mod M。其中 a,b,c 两两互质。

考虑一下那个互质要怎么用。

(以下运算未说明均在模 P 意义下进行)考虑构造成如下形式:2^{k ab} + 2^{k ab} = 2^{k ab + 1},然后可取 x = 2^{ka},y = 2^{kb}, z = 2^{(kab+1)/c}

也就是求一个 k 使得 kab + 1 \equiv 0 \mod c,因为 a,b,c 两两互质,可以使用扩展欧几里得算法解出一组合法答案。

但是当 P = 2^c 时我们的 x,y,z 可能是 0,这时需要特殊处理。若 a > 1x = \frac{m}{2}, y = z = 1,b > 1 类似,否则 c > 1x = y = z = \frac{m}{2},再否则 a=b=c=1,取 x = y = 1, z = 2

必要与充分条件

有些题目需要你判断能否构造出答案。此时一般可以得到一个较为明显的必要条件,而往往这个条件同时也是充分的,我们只需对于符合这个条件的情况进行构造。

以及,对于一些需要求出最优解的题目,存在一个显然的上界。而这个上界或许是可以构造出来的,我们只需给出一个合法的构造。这类题目通常会让你输出方案,而不是求解答案,因为后者往往是容易的。若是这样,则需考虑一下是不是这类题目。

1444D Rectangular Polyline

首先必要条件:横竖的线段都必须能划分为两个长度相等的集合,且横竖线段个数相等。

然后我们来构造方案:横竖线段中,取第一个集合为正,第二个集合为负,然后先随意两两匹配,得到一些向量,并且我们知道这些向量的和为 0

考虑用它们围成一个凸多边形,然后如果我们先走 x 后走 y 的话,第一象限和第三象限的向量的行走路线在凸多边形外,二四在形内。

也就是说只有在形内的二四象限的向量的轨迹可能相交,要是其中某一个象限不存在就好了。仔细想想是可以做到的,我们把横竖线段排序后匹配,自然二/四象限中会有一个不存在。

CF1450E Capitalism

首先这张图一定是二分图。

既然是最大减去最小,我们只关心它们之间的相对大小关系,那么不妨定一个 0,我们先枚举节点 s 的权值为 0

考虑其它的元素,它们的权值最大能是多少呢?考虑对于无向边,自然 d_u \leq d_v + 1d_v \leq d_u + 1 是必要条件。对于有向边,d_v \leq d_u +1d_u \leq d_v -1 。因此,如果对于 (u,v,0),我们连边 u \leftrightarrow v,边权 1;对于 (u,v,1),我们连边 u \rightarrow v,边权 1v \rightarrow u,边权 0,此时 u 的权值一定不大于 su 的最短路长度(如果存在负权回路,自然不存在任何合适的权值)。

同时,如果将到节点 u 的最短路径长度作为其权值,我们发现这恰好满足题目给定的限制。对于 (u,v,0),显然 d_u \leq d_v + 1,由于是二分图 d_ud_v 奇偶性不同,因此 d_u \neq d_v。若 d_u = d_v -1d_u = d_v + 1 都是符合题意的,若 d_u < d_v - 1,不满足 d_v \leq d_u + 1,矛盾。(u,v,1) 的情况类似。

因此枚举 s,求解最短路即可。

CF1442E Black, White and Grey Tree

考虑只有黑点和白点的情况,显然可以把颜色相同的联通块缩起来,得到一棵黑白相间的树。

先考察一条长度为 n,黑白相间的链,此时容易观察到它需要 \lfloor \frac{n}{2} \rfloor + 1 次操作。对于一棵树,考察它的直径,若其长度为 x,显然操作次数的下界是 \lfloor \frac{x}{2} \rfloor + 1,而这个下界是可以构造得到的(每次删去颜色相同的叶子)。

对于灰点的处理不在这次讨论的主题内,这里略去。

缩放条件/增强问题

和不等式证明中的放缩很类似,有时直接解决更强的问题,反而会更加简单。

有两个序列 AB 长度为 n,元素均为 [1,n] 之间的整数。现要求从 AB 中各选一个(非空)集合使得它们的和相等。

做法:考虑在 AB 中选两个连续段来达成要求。也就是 SA_i - SA_j = SB_k - SB_l,所以 SA_i - SB_k = SA_j - SB_l。假设 SA_n > SB_n,对每个 SA_x 我们找到最大的 SB_y \leq SA_x,如果这两个相等直接找到了答案,接下来我们认为它们不相等。因为 \forall i B_i \leq n,所以 SA_x - SB_y \leq n。因为有 n+1 个这样的 x[1,n] 只有 n 个数,一定有两个相同。

计数构造

这一类问题是,需要你构造一个组合对象,使得它的某个计数问题的答案恰好为题目给定的某个参数。常用的手段是:二进制拆分/贪心选取最大可选的决策等。

CF1396E Distance Matching

待更新。

构造一个(有向)简单图,使得它的哈密顿路径数量恰好为 k

k \leq 10^5, n = 20

构造一条 18 个点的链,每个点像前面一个点和后面所有点连边。这样从倒数第 i 个点走到最后的方案数就是 2^i,把 k 二进制拆分后,从源点向为二进制中为 1 的位置连边。

构造一个 n \leq 20, m \leq 120 的二分图(允许重边),使得完美匹配数量恰好为 k(k \leq 10^9)

和上题类似地,连一条红边可以让方案数多 2^i。但是这个题里面二进制拆分可能不够用,可以三进制拆分。

构造一个长度 \leq 10^5 串使得其本质不同子串数量为 k (k \leq 10^9)

构造类似 \texttt{aaabbccccdee} 这种串。假设每种字符有 \{a_1,a_2 \ldots a_k\} 个,本质不同子串数量是 \binom{n+1}{2} - \sum \binom{a_i}{2},选取 \binom{n+1}{2} \geq k 的最小 n 然后贪心地选取最大的 a_i 即可。

调整法

通过调整使得当前状态靠近满足题意的状态,观察到某个值往某个方向一直运动,即可以在证明调整一定能结束。

有一个 n \times n 的矩阵,每次可以将一行或者一列的符号取反,请进行若干次调整使得所有行和所有列非负。

|a_{i,j}| \leq 100

做法:每次找不合法的行或者列操作,然后所有元素的和一定是增大的,因此一定可以调整结束。

THUPC 母亲节的礼物

待更新。

范围讨论

有的题看起来大部分情况答案是显然的,但是比较小的情况中会出现一些讨论不清楚的东西,可以考虑对小范围暴力处理。

CF1461F Mathematical Expression

除了 +-* 之外的情况都比较简单,只考虑全体符号都合法的情况。

当然不会用 -,那么什么时候 +,什么时候 * 呢?

也就是划分为若干段,最大化每段乘积之和。

考虑 0,如果某一段包含 0 且长度大于 1,不如把它分为 0 前后的两段。

因此我们可以原序列从 0 处分成若干个不包含 0 的段,分别做。

一般来说我们是希望全部乘起来,这样明显大很多。但是有些乘积比较小的情况,可能在 1 附近摆 + 反而更优。

先把一段开头和结尾的 1 去掉(当然全是 +)。考虑其他数的乘积,如果比较大的话,就直接全部乘起来。否则,我们知道不是 1 的位置是很少的,并且最大答案也是很小的。我们可以 dp,注意分段的末尾只可能是一个不是 1 的位置,最多只有 \log w 个,暴力 dp 就可以了。

CF1493E Enormous XOR

如果 LR 最高位不同,似乎可以使用 011 \ldots 110100 \ldots 000 构造得到上界,但是当 LR 极小的情况下确有些讨论不清楚的情况。

如果 LR 最高位相同,当然要让最高位是 1,那么 S(L) 就只能选 0 或者 1 了。如果 [L,R] 这个区间比较大的话,01 都可以取到(长度超过 4 就可以了),那答案就相当于是 R \operatorname{bitor} 1但是很小的时候又有一堆讨论不清楚的大情况。

发现讨论不清楚的时候 R - L 总是很小,那我们直接在它比较小的时候大暴力,就可以规避掉一切讨论。

问题转化

并不仅限于构造性问题的方法,很多问题都是,在进行若干步转化之后,转化为某个更强/更弱/等价的问题,进而通过转化后的问题的方法来解决原问题。

CF1503D Flip the Cards

注意到,对于两张牌,如果 \max(a_1,b_1) < \min(a_2,b_2),这两张牌无论怎么摆都不合法。略加考虑即可发现每张牌的两个数字必须一个小于等于 n,另一个大于 n

f(i) 表示,数字 i 那张牌另一面的数字。考虑称较小面向上的牌为一类牌,否则为二类牌。也就是要将牌分为一类和二类,然后显然把二类放在一类后面,同时要求在一类和二类中,他们较小的一面 x 上升时,f(x) 都是下降的。

因此原问题至少是:将 f(1 ... n) 划分为两个下降子序列。同时,任何一种划分方案,都对应着原问题的一种分类方案。

接下来我们只需最小化答案。也就是,对于每一个 x,把它划分进某一个子序列会付出 1 的代价。

考虑:对于某一个位置,如果它前面的最小的 f(x) 都比后面最大的 f(x) 大,那么这两段问题是独立的。考虑对每一段独立求解。注意到在每一段中,考虑一个数,若你可以把它划分进第一个和第二个子序列中,你一定要将它划分进栈顶较小的那个。因为在它之后,一定存在一个数大于前缀最小值(较小的栈顶和自己),如果自己放到了另一个栈中,后面那个元素就无法划分了。因此若认为两序列无区别,划分方案是唯一的。

二选一构造

很无聊,出这种题简直是有毛病

CF1439B Graph Subset Problem

CF1404D Game of Pairs