学完后,你应能把并查集合并历史显式建成 Kruskal 重构树,用 LCA 回答“两点何时连通”,并利用 XOR 权值的最高不同位递归削减完全图。
前置:Kruskal、并查集、LCA、二进制 Trie、分治。
Kruskal 普通实现只保留最终 DSU,丢掉“什么时候合并”。重构树在每次成功合并两个分量时新建父节点,节点权为当前边权/时间,两个旧根作为孩子。原点是叶子,内部点权沿根方向不降。
两个原点的 LCA 正是首次把它们并入同一分量的合并节点。因此:
$$ \operatorname{value}(\operatorname{LCA}(u,v)) =\min{k:\ u,v\text{ 在前 }k\text{ 条边中连通}}. $$
XOR-MST 则使用最高位分层。若一组数在位 $b$ 同时含 0/1,任意连接两组的边都至少花 $2^b$;生成树必须至少选一条跨边,而组内可独立递归。只需求两组间最小 XOR,而不是显式生成所有跨边。
2*n 开。多组连通简单无向图,边按输入编号 $1..m$。每个询问 $[l,r]$ 求最小 $k$,使编号在该区间内的所有顶点使用前 $k$ 条边两两连通。总 $n\le10^5$,总 $m,q\le2\times10^5$。
边按编号递增处理,每次连接两个不同分量就新建合并节点。对阈值 $k$,区间相邻点全部连通则由传递性整个区间连通;整个区间连通也必然包含每对相邻点。因此最小共同阈值是相邻阈值最大值。
建树与 LCA 预处理 $O((n+m)\alpha(n)+n\log n)$,区间最大值用迭代线段树,每问 $O(\log n)$。
process input edges by index; every successful DSU merge creates a new parent node
new node value = current edge index; its children are the two old component roots
preprocess LCA on the reconstruction tree
need[i] = value(LCA(original_vertex_i, original_vertex_i+1))
answer(l,r) = max(need[l .. r-1]), or 0 when l == r
完整 GNU C++17 参考实现见附件:CodeForces-1706E.cpp
若询问顶点集合不是编号连续区间,相邻编号链不再覆盖集合;可按 DFS 序、虚树或直接取集合在重构树上的最小公共祖先,取决于查询形式。
完全图有 $n\le2\times10^5$ 个点,点 $i$ 带值 $a_i<2^{30}$,边权为 $a_i\oplus a_j$。求 MST 权值。
当前范围内所有数共享更高位。按位 $b$ 分开后,任意跨边权均大于任一只由更低位构成的数;MST 可先在两侧各自连通,再用一条最小跨边连接。多用跨边会形成环,删除其中一条不更差。
递归处理两侧,跨边低位最小 XOR 用 Trie 求。排序与 30 层分治,当前实现复杂度 $O(n\log^2 A)$、空间 $O(n\log A)$ 的峰值;$\log A\le30$。
sort and deduplicate values
solve(group, bit):
split group by current bit
answer = solve(zero_side, bit-1) + solve(one_side, bit-1)
if both sides exist:
build a lower-bit binary trie for the smaller side
answer += 2^bit + minimum lower-bit XOR across the split
return answer
完整 GNU C++17 参考实现见附件:CodeForces-888G.cpp
本题不是“所有完全图都能 Trie”。可分治是因为最高不同位严格支配全部低位;若边权改成按位 AND 或普通差值,递归结构和跨边性质都要重证。
CodeForces-891C Envy 要判断每个询问给定的边集能否同时出现在某棵 MST。提示方向:按权值处理询问边,在全局 DSU 只合并更轻边;同一询问、同一权组用临时可回滚 DSU 检查是否成环。它把本章“同权批次不能提前合并”的原则提升到离线多询问,不作为后续硬前置。
先用逐步 DSU 暴力核对重构树 LCA 阈值,再完成区间 RMQ。XOR-MST 先对 8 个数枚举完全图 MST,对照递归拆分;卡住时只展开“最高位下界”,不要直接背 Trie 代码。最后阅读 Envy 的同权离线框架并写出临时 DSU 必须回滚的原因。