CF1408

ABCD 之前做了,懒得再看了。

E \((\texttt{Easy} \ 2 / 1)\)

为每个集合和每个数分别建立一个点,若 \(x \in A_i\) 则在 \(A_i\)\(x\) 之间连一条边权为 \(a_i + b_j\) 的边。

不难发现题目要求等价于这张图上不存在环,跑最大生成树即可。

时间复杂度 \(\mathcal{O}((n + m) \log (n + m))\)

F \((\texttt{Easy} \ 2 / 1)\)

发现如果 \(n\)\(2\) 的幂次我们就可以很轻易地把所有数合并为一个数。

于是直接仿照 \(\rm RMQ\) 算法,设 \(d = \left\lfloor \log n \right\rfloor\),依次对 \([1, 2^t]\)\([n - 2^t + 1, n]\) 进行合并即可。

时间复杂度 \(\mathcal{O}(n \log n)\)

G \((\texttt{Easy} \ 3 / 2)\)

发现一个性质,就是如果当前的集合合法,则至多有一个集合外的点,满足将这个点加入集合后集合依然合法。所以一个集合如果增长,方向是唯一的。于是我们可以得到所有合法集合要么不交、要么包含,不难想到 Kruskal 重构树。

经过观察可以看出,一个集合合法的必要条件是它是由重构树的某个子树组成的集合。不难发现,重构树上的点 \(u\) 合法当且仅当 \(u\) 被合并时其内的边连满了,于是根据这个直接设 \(f_{u, i}\) 表示以 \(u\) 为根的子树分成 \(i\) 个集合的方案,进行一个树形 dp 即可。

时间复杂度 \(\mathcal{O}(n^2)\)

H \((\texttt{Medium} \ 5 / 3)\)

看到 flow 的 tag 和官方题解的 observation 2 就会了这不是都提示完了吗

\(0\) 的个数为 \(c0\),注意到答案至多为 \(m = \left\lfloor \frac{c0}{2} \right\rfloor\),我们可以考虑把原序列分裂为前缀 \(L\) 和后缀 \(R\),使得 \(L\) 中恰好有 \(m\)\(0\)。这么分有什么用呢?假如我们现在选出了 \(k \le m\) 个互不相同的整数,那么我们只需为 \(L\) 中的数选取左边的 \(0\)\(R\) 中的数选取右边的 \(0\) 即可,因为剩下的一定可以匹配上。通过分出 \(L, R\),我们现在只用考虑一边的 \(0\)

显而易见地,对于 \(L\) 中的重复的数,我们只用保留最右边的那个;对于 \(R\) 中的重复的数,我们只用保留最左边的那个。于是我们可以建出网络流模型:为每个不同的正数建立一个点,为每个位置建立一个点;源点向数连边,数向其位置连边,\(0\) 向汇点连边,\(L\) 内的边从右往左连,\(R\) 内的边从左往右连。肯定是不能直接网络流的,我们考虑如何优化它。

模拟最大流感觉没什么思路,但是最大流等于最小割,我们考虑如何求最小割。因为位置之间的边流量是 \(\infty\),所以不能割去它们;因为割数向位置连的边不如割源点向数连的边,所以不会割去它们。剩下两种边:

  • \(0\) 连向汇点的边;
  • 源点连向数的边。

对于前者,以 \(L\) 为例,发现割前面的边比割后面的边要更优,所以最终割掉的一定是一段前缀里所有的 \(0\) 向汇点连的边。这下就简单了,我们可以枚举 \(L\) 里割了多少 \(0\),然后用线段树维护 \(R\) 里割一段后缀所需的总代价即可。线段树需要支持区间加、整体 \(\min\)

时间复杂度 \(\mathcal{O}(n \log n)\)。注意这样算出来的答案要和 \(m\)\(\min\)

I \((\texttt{Easy} \ 3 / 3)\)

不知道大家为啥都在写多项式,这里提供一个大概率本质相同的比较简单的做法,时间复杂度同样是 \(\mathcal{O}(2^cck^3)\)

首先有一个很 sb 的 dp,就是设 \(f_{i, j, s}\) 表示前 \(i\) 个数操作了 \(j\) 次,当前的异或和为 \(s\) 的方案数,我们考虑如何去优化它。

发现一个没有利用上的条件:\(a_i\) 是不同的。我们不妨思考一些基于值域上的均摊的性质。先假设 \(a_i \ge 16\),设 \(t\) 为最小的正整数,使得 \(d > 3\) 并且 \(x\) 二进制下第 \(d\) 位为 \(1\),那么显然第 \(d\) 位以上的位是不可能改变的,我们可以把这部分去掉再在最后异或回来。我们把 \(a\) 数组按照每一个数对应的 \(d\) 从小到大排序,那么 dp 到 \(i\) 的时候值域就就可以缩减到 \(2^d\) 了。

对于一个 \(d\),符合条件的 \(x\)\(k \times 2^{c - d - 1}\) 种,所以所有 \(a_i\)\(2^d\) 之和不会超过

\[\sum\limits_{i = 0} ^ {c - 1} k \times 2^{c - d - 1} \times 2^d = \mathcal{O}(2^c ck) \]

于是总的时间复杂度就是 \(\mathcal{O}(2^cck^3)\)\(k, c\) 较小的情况需要注意一些细节。

posted @ 2022-09-29 20:19  Scintilla06  阅读(13)  评论(0编辑  收藏  举报