【题解】Solution Set - NOIP2024集训Day8 并查集和可持久化并查集

【题解】Solution Set - NOIP2024集训Day8 并查集和可持久化并查集

https://www.becoder.com.cn/contest/5453

*注:如不加特殊说明,α 均代表并查集的小常数,有 αlog


「AGC002D」Stamp Rally

从小到大枚举边,加入就合并。(x,y,z) 就是问第一次 x 所在集合大小 + y 所在集合大小 z 的时候是多少。(如果 x,y 在同一个集合中只能算一次)。这样是 O(qmα) 的。


考虑改成整体二分。整体时间复杂度为 O(qlogmα)

只是比较难实现,每次新加边的时候要精细实现,不然很容易变成 O(qmlogmα)

具体的,每次加边的时候记录所有的修改位置和之前的量(所以不能路径压缩),加完边,不清空,直接递归右边,然后再清空回去,递归左边。


或者,更直接一点我们直接把并查集可持久化,每次询问都直接二分,然后 O(logq) 在可持久化并查集上面查。总共就是两只 log


还有一个 kruskal 重构树的 O(qlog2n) 做法,有时间去复习一下。

kruskal 重构树本质上也是也就是在维护可持久化并查集的过程。—— yly


代码写的是整体二分。


「 CF1659E」AND-MEX Walk

观察样例可以发现,答案只有可能 0/1/2。(如果没有猫娘和揭的提醒,可能都想不到 /lb

考虑把每个 wi 二进制拆分,然后按顺序放在表格的每一列。

我们发现如果要把每个 wi 转化为 w1&&wi 其实就是把每一行的第一个 0 一直填充到行末。

考虑以下事实:

  1. 如果存在某一行都是 1,那么答案就是 0。因为所有的值都大于 0
  2. 否则,我们考虑最后一行。
    1. 如果最后一行第一次出现 0 不是最后出现的或者就是最后一次出现,那么答案就肯定是 1。考虑最后两行,从左至右一定是:一段 3,一段 2,一段 0
    2. 否则,答案就应该是 2。考虑最后两行,从左至右一定是:一段 3,一段 1,一段 0

简述一下题解的证明:

考虑反证。如果最终答案 3,那么在 & 的前缀中一定存在 1/2。我们注意到 1=(01)2,2=(10)2,无论这二者谁排在前面,都会使末两位中的某一位上面一直保持为 0,从而此二者一定不能共存,与假设中 1/2 同时存在矛盾!

感觉还是挺妙的。根据结论来证,难猜的结论。


所以现在我们把一个计算题,转化成了判定题,因而要求的东西就明朗了。

首先判定答案为 0 的情况。

对于二进制的每一位,如果一条边权在该位上为 1,就连边,然后用并查集维护联通块,查询的时候如果 u,v 在同一个联通块内,答案即为 0

然后判定 1

类似的,我们把末两位均为 1 的边连上,维护每个联通块。然后再把把末两位为 (10)2 的边连上,同样维护每个联通块。查询的时候,就看 u 在第一个图里面的联通块,和 v 在第二个图里面的的联通块是不是有交集。

和下面 「JOI Open 2016」销售基因链 又很类似,可以重标号转化为一个二维数点问题。


「JOI Open 2016」销售基因链

其实这道题想到 trie 就简单了。

考虑对所有串正反分别建一棵 trie。现在问题就转化为一个典问题:给定两棵子树求叶子节点的交集。

首先按照 dfs 序对其中的一棵树重编号,让子树内叶子节点变为连续的,然后另一棵子树线段树合并,最后求一下区间和就好了。


「Ynoi2010」Fusion tree/融合树

考虑给树上节点重编号。使得每个节点往下的那些节点都是连续的,于是一次修改就等价于线段树上的区间加,单点加,区间异或和。

现在难点在于如何,区间加,区间异或和。

每次区间加都是 1,这可能挺关键。而且区间一共只有 n 种,每种还互不相交。

不会了。😭


对于一棵 0-1 trie,我们可以对所有数字 +1,然后维护异或和。

OI-Wiki

posted @   CloudWings  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示