洛谷p3377
还是第一次用读入挂
这题如果用左偏树,不路径压缩貌似一定会在最后一个案例T掉
但是路径压缩一定要注意删了某一个结点后,其他的节点父亲结点有可能指向这个结点,所以要接的让这个结点的父结点指向新归并的结点
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 100005;
int parent[N];
class Node {
public:
int left, right, val, dist;
}tree[N];
int find_parent(const int& x) {
int p = x;
while (p != parent[p]) {
p = parent[p];
}
int adjust = x;
while (adjust != parent[adjust]) {
int next = parent[adjust];
parent[adjust] = p;
adjust = next;
}
return p;
}
int merge(int x, int y) {
if (x == 0 || y == 0)return x + y;
if (tree[x].val > tree[y].val || (tree[x].val == tree[y].val && x > y))swap(x, y);
tree[x].right = merge(tree[x].right, y);
parent[tree[x].right] = x;
if (tree[tree[x].left].dist < tree[tree[x].right].dist)swap(tree[x].left, tree[x].right);
tree[x].dist = tree[tree[x].right].dist + 1;
return x;
}
int remove(int x) {
int left = tree[x].left;
int right = tree[x].right;
tree[x].val = -1;
parent[left] = left;
parent[right] = right;
return parent[x] = merge(left, right);
}
int inline read(){
int x = 0, f = 1; char ch = getchar();
while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
int main() {
int n = read(), m = read(), o, x, y, left, right;
tree[0].dist = -1;
for (int i = 1; i <= n; ++i) {
tree[i].val = read();
parent[i] = i;
}
while (m--) {
o = read();
x = read();
left = find_parent(x);
if (o == 1) {
y = read();
int right = find_parent(y);
if (tree[x].val == -1 || tree[y].val == -1 || left == right) {
continue;
}
merge(left, right);
}
else {
if (tree[x].val == -1) {
printf("-1\n");
}
else {
int ans = tree[left].val;
printf("%d\n", ans);
remove(left);
}
}
}
return 0;
}