左偏树本质是堆,在满足父亲比两个儿子的\(val\)都大(小)的时候保证
\[dist[ls] >= dist[rs]\]
\[dist[x] = dist[rs] + 1\]
于是就支持\(merge\)快速合并
\(pop\)就乱搞,合并两子树就行
可以用并查集维护所在堆
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| int ch[N][2], dist[N], fa[N], val[N];
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
int merge(int x, int y) { if (!x || !y) return x | y; if (val[x] > val[y]) swap(x, y); ch[x][1] = merge(ch[x][1], y); if (dist[ch[x][0]] < dist[ch[x][1]]) swap(ch[x][0], ch[x][1]); dist[x] = dist[ch[x][1]] + 1; return x; }
inline void pop(int x) { val[x] = -1, fa[ch[x][0]] = fa[ch[x][1]] = fa[x] = merge(ch[x][0], ch[x][1]); }
for (int i = 1; i <= n; ++i) fa[i] = i;
int fx = find(x), fy = find(y); fa[fx] = fa[fy] = merge(fx, fy);
|