**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;
}
标签:dist,rs,int,tr,fa,ls,模板,左偏
From: https://www.cnblogs.com/UeesugiSakura/p/18561735