0%

板子 左偏树

左偏树本质是堆,在满足父亲比两个儿子的\(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;

// merge
int fx = find(x), fy = find(y);
fa[fx] = fa[fy] = merge(fx, fy);