可撤销并查集错误地使用了路径压缩,谁能解释一下为什么还能 AC?
#include <iostream>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#define ll long long
#define db double
#define ls p << 1
#define rs p << 1 | 1
#define L(i, j, k) for (int i = (j); i <= (k); ++ i)
#define R(i, j, k) for (int i = (j); i >= (k); -- i)
#define pii pair <int, int>
#define vi vector <int>
#define pb emplace_back
#define sz(v) ((int) v.size())
#define mem(f, x) memset(f, x, sizeof (f))
using namespace std;
template <typename T> void rd(T &res) {
res = 0; bool f = 0; char ch = getchar();
while (ch < '0' || ch > '9') f |= ch == '-', ch = getchar();
while (ch >= '0' && ch <= '9') res = (res << 1) + (res << 3) + (ch ^ 48), ch = getchar();
res = (f ? -res : res);
}
template <typename T, typename ...Args>
void rd(T &res, Args &...res_) { rd(res), rd(res_...); }
const int N = 4e5 + 10;
int n, m, k, f[N], h[N], top;
struct Edge { int x, y; } e[N];
struct SegmentTree { int l, r; vi t; } t[N];
struct Merge_info { int x, y, h; } stk[N];
vi em;
void build(int p, int l, int r) {
t[p] = {l, r, em};
if (l == r) return ;
int mid = l + r >> 1;
build(ls, l, mid), build(rs, mid + 1, r);
}
void insert(int p, int l, int r, int id) {
if (l <= t[p].l && t[p].r <= r) { t[p].t.pb(id); return ; }
int mid = t[p].l + t[p].r >> 1;
if (l <= mid) insert(ls, l, r, id);
if (r > mid) insert(rs, l, r, id);
}
int get_fa(int x) { return x == f[x] ? x : f[x] = get_fa(f[x]); } // 聪明的路径压缩
void merge(int x, int y) {
int fx = get_fa(x), fy = get_fa(y);
if (h[fx] > h[fy]) swap(fx, fy);
stk[++ top] = {fx, fy, h[fy]};
f[fx] = fy;
h[fy] += (h[fx] == h[fy]);
}
void solve(int p) {
bool flag = true; int cur = top;
for (int i : t[p].t) {
if (get_fa(e[i].x) == get_fa(e[i].y)) {
L(j, t[p].l, t[p].r) puts("No");
flag = false; break;
}
merge(e[i].x, e[i].y + n), merge(e[i].x + n, e[i].y);
}
if (flag) {
if (t[p].l == t[p].r) puts("Yes");
else solve(ls), solve(rs);
}
while (top > cur) h[stk[top].y] = stk[top].h, f[stk[top].x] = stk[top].x, -- top;
}
signed main() {
// ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
rd(n, m, k);
build(1, 1, k);
L(i, 1, n << 1) f[i] = i;
L(i, 1, m) {
int l, r;
rd(e[i].x, e[i].y, l, r);
insert(1, l + 1, r, i);
}
solve(1);
return 0;
}