如果你在合并时特判了两点已在一个集合就直接结束:当前版本的根编号可能还是 0,这会导致之后退回当前版本时挂掉
例如这样是错的:
void Merge(int u, int v, int now, int k) {
pr q1 = Find(u, k), q2 = Find(v, k);
int f1 = q1.first, d1 = q1.second;
int f2 = q2.first, d2 = q2.second;
if (f1 == f2) return ;
if (d1 < d2) swap(u, v), swap(f1, f2), swap(d1, d2);
Update(1, n, f2, f1, max(d1, d2 + 1), rt[now], rt[k]);
Update(1, n, f1, f1, max(d1, d2 + 1), rt[now], rt[now]);
return ;
}
但这样是对的:
void Merge(int u, int v, int now, int k) {
pr q1 = Find(u, k), q2 = Find(v, k);
int f1 = q1.first, d1 = q1.second;
int f2 = q2.first, d2 = q2.second;
if (f1 == f2) return (void) (rt[now] = rt[k]);
if (d1 < d2) swap(u, v), swap(f1, f2), swap(d1, d2);
Update(1, n, f2, f1, max(d1, d2 + 1), rt[now], rt[k]);
Update(1, n, f1, f1, max(d1, d2 + 1), rt[now], rt[now]);
return ;
}