1. 程式人生 > 實用技巧 >【模板】左偏樹(可並堆)

【模板】左偏樹(可並堆)

題目

見洛谷

\(Code\)

#include<cstdio>
#include<iostream>
using namespace std;

const int N = 1e5 + 5;
int n , m , fa[N];
struct Lheap{
	int ls , rs , val , bz , dis;
}h[N];

inline 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 (h[x].val > h[y].val || (h[x].val == h[y].val && x > y)) swap(x , y);
	h[x].rs = merge(h[x].rs , y);
	if (h[h[x].ls].dis < h[h[x].rs].dis) swap(h[x].ls , h[x].rs);
	h[x].dis = h[h[x].rs].dis + 1;
	return x;
}

int main()
{
	scanf("%d%d" , &n , &m);
	for(register int i = 1; i <= n; i++) scanf("%d" , &h[i].val) , fa[i] = i;
	int x , y , op;
	while (m--)
	{
		scanf("%d%d" , &op , &x);
		if (op == 1)
		{
			scanf("%d" , &y);
			int u = find(x) , v = find(y);
			if (h[x].bz || h[y].bz || u == v) continue;
			fa[u] = fa[v] = merge(u , v);
		}
		else{
			if (h[x].bz) {printf("-1\n"); continue;}
			int rt; printf("%d\n" , h[rt = find(x)].val);
			h[rt].bz = 1 , fa[rt] = fa[h[rt].ls] = fa[h[rt].rs] = merge(h[rt].ls , h[rt].rs);
		}
	}
}