一、并查集基础
并查集需要初始化,即 fa[i] = i,表示 i 的父节点是它自己。
二、题目实战
1. 团伙
给定 n 个人,m 个关系,每个关系为 x 和 y 是朋友或敌人。求最多的团体数。(两个人在一个团体内当且仅当这两个人是朋友)
'敌人的敌人就是朋友'。如果一个人有两个或更多敌人,这些敌人应该被合并。
我们如果发现两个人是朋友,就无条件合并。
如果设 x 和 y 是敌人,那么 x 和 y 的敌人就是朋友。
给每个人开两个域:
- x:表示 x 本身
- x + n:表示 x 的敌人集合
输入处理逻辑:
- x 和 y 是朋友:
union(x, y) - x 和 y 是敌人:
union(x + n, y)和union(x, y + n)
2. 程序自动分析
给定一些判定条件(xi = xj 或 xi ≠ xj),判断是否有一组解满足全部条件。
只有相等/不相等两种条件。先处理相等的操作,把所有相等的放一个集合里。再处理不等,判断是否在一个集合里。
注意 n ≤ 10^9,直接开数组会内存溢出(RE)。需要使用离散化处理。
离散化步骤:
- 收集所有约束涉及的 x, y。
- 去重。
- 排序。
- 给每个唯一的数值分配一个连续的小下标。
- 用并查集先处理相等的变量,再遍历所有的不等约束。
3. 集合
给定区间 [a, b](1 ≤ a ≤ b ≤ 10^5)和 m 个查询,问两个数 x、y 是否在同一个集合里。
集合规则:如果两个数有公共的质因子,它们属于同一个集合(关系有传递性)。
'有公共质因子'可以理解为:用这个质因子当'桥',把所有包含它的数合并到一起。
例如:
- 6 的质因子是 2、3
- 8 的质因子是 2
- 9 的质因子是 3
用质因子 2 合并 6 和 8,用质因子 3 合并 6 和 9,最后 6、8、9 都在一个集合里。
实现方式:用质筛求质数,符合条件点的连边(与自己的质因数),最后进行连通性查询。


