【模板】可并堆 之 左偏树

**P3377【模版】左偏树/可并堆**

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;

int n, m;
struct Heap {
	int ls, rs;
	int dist, val, fa;
} tr[N];

int fifa(int x) {
	return tr[x].fa == x ? x : tr[x].fa = fifa(tr[x].fa);
}

int merge(int x, int y) 
{
	if (!x || !y)
		return (x + y);
		
	if (tr[x].val > tr[y].val)
		swap(x, y);
		
	tr[x].rs = merge(tr[x].rs, y);
	
	if (tr[tr[x].ls].dist < tr[tr[x].rs].dist)
		swap(tr[x].ls, tr[x].rs);
		
	tr[x].dist = tr[tr[x].rs].dist + 1;
	
	tr[tr[x].ls].fa = tr[tr[x].rs].fa = tr[x].fa = x;//
	
	return x;
}

void pop(int x) 
{
	printf("%d\n", tr[x].val);
	
	tr[x].val = -1;
	
	tr[tr[x].ls].fa = tr[x].ls;
	tr[tr[x].rs].fa = tr[x].rs;
	tr[x].fa = merge(tr[x].ls, tr[x].rs);//
}

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &tr[i].val);
		tr[i].fa = i;
	}
	int opt, x, y;
	for (int i = 1; i <= m; i++) {
		scanf("%d%d", &opt, &x);
		switch (opt) {
			case 1: {
				scanf("%d", &y);
				if (tr[x].val == -1 || tr[y].val == -1) 
					continue;
				int fax = fifa(tr[x].fa);
				int fay = fifa(tr[y].fa);
				if (fax == fay) continue;
				merge(fax, fay);
				break;
			}
			case 2: {
				if (tr[x].val == -1) printf("-1\n");
				else {
					int faa = fifa(tr[x].fa);
					pop(faa);
					break;
				}
			}
		}
	}
	return 0;
}
posted on 2024-11-21 22:51  Ueesugi_sakura  阅读(1)  评论(0编辑  收藏  举报