构造专题

CF1198C Matching vs Independent Set

给一个无向图,\(3 \times n\) 个点, \(m\) 条边,请找大小为 \(n\) 的点独立集或边独立集。
\(n,m \le 5 \times 10^5\)

解题思路:

不难发现一个大小为 \(n\) 的独立集和一个大小为 \(n\) 的边独立集,两个点数加起来最多为 \(3 \times n\) 的。
然后当一个边独立集中不能再从他点集的补集中加边时,就说明他点集的补集是一个点独立集。
所以考虑任选一个极大边独立集,那么分讨一下是选边独立集还是点独立集就行。

CF618F Double Knapsack

给了你两个数组 A 和 B,请问能不能从 A,B 中各选一个集合使得和相同。
\(n \le 10^6,1 \le A_{i},B_{i} \le n\)

解题思路:

考虑从中选出的集合不同的和最多有 \(\frac{n \times (n + 1)}{2}\) 种不同的数字。
然后一个数组的子段的个数也为 \(\frac{n \times (n + 1)}{2}\) 个。
我们猜测他子段也可以做。
\(suma_{i} = sum_{j=1}^i a_{j}, sumb_{i} = \sum_{j=1}^i b_{j}\)
强定 \(suma_{n} \le sumb_{n}\)
\(p_{i} = min_{suma_{i} < sumb_{j}} j\),则有 \(1 \le sumb_{p_{i}} - suma_{i} \le n\)
由于对于任意的 \(0 \le i \le n\),都有 \(p_{i}\),所以一定存在两个整数 \(i,j\) 使得 \(sumb_{p_{i}} - suma_{i} = sumb_{p_{j}} - suma_{j}\)
于是就能找到一个解。
用双指针能做到 \(O(n)\)

感觉构造还是需要先找到性质,再转化问题才能做啊。
而且我们也可以通过放缩范围来方便构造。

CF2129C3 Interactive RBS (Hard Version)

题目大意:

有一个长为 \(n\) 的只有左右括号的未知的字符串,每次可以向交互库以任意顺序给定不超过 1000 的若干个可以重复的位置,交互库会回答拼成的串中多少个匹配字串。
需要输出这个串。
\(n \le 1000\),次数上限 100 次。

解题思路:

先考虑 C1 也就是 550 次操作怎么做。
考虑由于初始是什么都不知道的,所以胡乱查询很难推理出字符串。
我们考虑找到第一个发生匹配的位置,那么就能确定一个左括号一个右括号。
这个可以通过二分前缀查询,只用十次操作。
那么由于 \(500 = \frac{1000}{2}\),我们有足够的步数去两两询问,所以我们考虑要构造一种方案去快速查询两个,并让他们能唯一确定。
我们发现可以询问 \((()(i i-1\) 即可唯一确定两个相邻的了。

C2:200次操作。
我们发现在 C1 的构造中两两查询的效率太低了,因为一次查询只能询问两个。
那么我们可以一次询问多对,并类似二进制来询问并唯一确定信息。
我们发现这样就可能超过长度 1000 的限制,所以我们考虑通过构造 \(i))i+1))i+1))i+2))i+2))i+2))i+2))\) 类似让他压缩成一个二进制数。
那么我们就可以通过 C2。

C3: 100次操作:
发现 C2 中相同位置互相影响是没事的,所以可以构造 \(i))i+1)i+1))i+2)i+2)i+2)i+2))\)
那么就能压进 100 次了。

赛时只想到了 C1,下一次看见这种类似解压的形式之后可以考虑通过进制来解决。

CF2124E Make it Zero

题目大意:

有一个长为 \(n\) 的序列 \(a\),每次可以选择一个长度为 \(n\) 的序列 \(b\),使得 \(0 \le b_{i} \le a_{i}\),而且存在一个 \(1 \le j \le n\) 使得 \(\sum_{k = 1}^{j}b_{k} = \sum_{k = j + 1}^{n} b_{k}\)
并将所有的 \(a_{i}\) 减去 \(b_{i}\),请构造一个最小的方案数使得 \(a\) 全为 \(0\)
\(n \le 2 \times 10^5\)

解题思路:

我被诈骗了 /ll
他在输出格式的时候写了个要求 \(cnt \le 17\),然后我就自然地想到了分治上了/ll

以后看到他要求最小步数的时候大概率是会很少的,\(O(1)\) 级别。

首先如果最大值大于其他数之和,那么一定无解。
其次他的和是奇数的话由于每次一定是减少个偶数那么也无解。

那么考虑一次消的情况,那么就是存在一个 \(j\) 满足 \(\sum_{k = 1}^{j} a_{k} = \sum_{k = j + 1}^{n} a_{k}\)
然后我们感觉他的 \(b\) 非常自由,于是大胆猜测他一定可以两步之内解决。

我们考虑找到一个最小的 \(j\) 使得 \(sum_{i = 1}^{j} a_{j} > sum_{i = j + 1}^{n} a_{j}\)
然后我们只需要在一步之内消掉 \(sum_{i = 1}^{j} a_{j} - sum_{i = j + 1}^{n} a_{j}\)
那么我们需要一步之内在 \(1 \sim j\) 的前缀中消掉 \(sum_{i = 1}^{j} a_{j} - sum_{i = j + 1}^{n} a_{j}\)
由于 \(j\) 是最小的 \(sum_{i = 1}^{j} a_{j} > sum_{i = j + 1}^{n} a_{j}\),所以 \(a_{j} > \frac{sum_{i = 1}^{j} a_{j} - sum_{i = j + 1}^{n} a_{j}}{2}\)

也就是说我们要求在 \(1 \sim j - 1\) 中找到 \(\frac{sum_{i = 1}^{j} a_{j} - sum_{i = j + 1}^{n} a_{j}}{2}\)
只要我们保证 \(\sum_{k = 1}^{j - 1} a_{k} \ge \frac{sum_{i = 1}^{j} a_{j} - sum_{i = j + 1}^{n} a_{j}}{2}\) 即可。

由于 \(a\) 中任意一个数的二倍都比和小,所以一定能找到。
那么就可以 \(O(n)\) 输出方案了。

CF2038 G Guess One Character

题目大意:

有一个长度为 \(n\) 的未知的 01 串,你可以进行不超过三次以下操作:
给定一个长度不超过 \(n\) 的 01 串,系统将返回这个串在隐藏的串里作为子串出现了多少次。
求出这个串中任意一个位置是什么。
\(n \le 3 \times 10^5\)

解题思路:

由于只需要输出 1 个位置的值,并且只有 \(3\) 次查询。
那么最特殊的位置一定是首/尾,因为他们没有前一个/后一个。

由于是对称的,我们不妨求 \(s_{1}\) 的值。
因为它前面没有值,所以我们可以通过长度为 \(1,2\) 的字串来区分它与后面的位置。
那么假设 \(s_{1} = '0'\),则有 \(cnt_{00}+cnt_{10}=cnt_{0}-1\)
所以我们询问 \(0,00,10\),如果它满足上面的条件,则 \(s_{1} = '0'\),否则 \(s_{1} = '1'\)

构造题一开始构造范围较大,可以通过合理的推理和猜测来一点一点缩小可能的构造范围

CF2029F:

题目大意:

有一个 \(n\) 个点的环, \(i\)\((i + 1) \mod n\) 有一条颜色为 \(B\) 或者 \(R\) 颜色的路。
给你每一条边的颜色,请判断任意两点之间是否存在一条回文路径,注意路径可以不是简单路径。
\(n \le 10^6\)

解题思路:

考虑判断回文是不好判断的,我们可以先找一些必要条件,也就是第一步的字符一定要与最后一步的字符相同。
但是如果有一个点两边的边均为 \(R\) 且有一个点的两边均为 \(B\),说明一定不合法。

所以整个环现在变成了若干个 \(R\) 再加一个 \(B\) 重复下去。
由于他允许反复走,所以不难发现连续段的长度的奇偶才是比较重要的。

也就是要求经过的连续段的奇偶要回文。
那么如果同时存在两个长度为偶数的连续段,由于偶数段一个位置的两边要么是两个偶数,要么是两个奇数,所以可以钦定一起一终来使答案为 NO。
然后开始观察样例,发现 \(RBRBRB\) 是不合法的,是因为我们在长度为奇数的段上的时候虽然不能立即确定 YES/NO,但是我们可以钦定要么同时向奇数的一侧走,要么同时向偶数的一侧走。

这样发现如果全都是长度为奇数的段的时候是构造不出来的,但只要有一个偶数段就一定能找出来。
也就是经过长度为偶数段一定可以。
那么就能找到本题的充要条件了,都是好判的。

posted @ 2025-02-22 17:56  positive_deviation  阅读(19)  评论(0)    收藏  举报