luogu3377 【模板】左偏树(可并堆)

ref

#include <iostream>
#include <cstdio>
using namespace std;
int n, m, a[100005], opt, uu, vv, fa[100005], ch[100005][2], dis[100005];
int myfind(int x){
	while(fa[x])	x = fa[x];
	return x;
}
int merge(int x, int y){
	if(!x || !y)	return x+y;
	if(a[x]>a[y] || (a[x]==a[y] && x>y))	swap(x, y);
	ch[x][1] = merge(ch[x][1], y);
	fa[ch[x][1]] = x;
	if(dis[ch[x][0]]<dis[ch[x][1]])	swap(ch[x][0], ch[x][1]);
	dis[x] = dis[ch[x][1]] + 1;
	return x;
}
void pop(int x){
	a[x] = -1;
	fa[ch[x][0]] = fa[ch[x][1]] = 0;
	merge(ch[x][0], ch[x][1]);
}
int main(){
	cin>>n>>m;
	for(int i=1; i<=n; i++)
		scanf("%d", &a[i]);
	while(m--){
		scanf("%d", &opt);
		if(opt==1){
			scanf("%d %d", &uu, &vv);
			if(a[uu]<0 || a[vv]<0)	continue;
			uu = myfind(uu);
			vv = myfind(vv);
			if(uu!=vv)	merge(uu, vv);
		}
		else{
			scanf("%d", &uu);
			if(a[uu]<0){
				printf("-1
");
				continue;
			}
			uu = myfind(uu);
			printf("%d
", a[uu]);
			pop(uu);
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/poorpool/p/9010590.html