并查集+kth。。
套个权值树状数组就可以。
把求k大转化为求n-k+1小。
注意一开始有n个size为1的集合,所以要先往bit_tree[1]上面加n。
我居然把fa[fx]=fy写成fa[fy]=fx(自闭
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cctype>
#include<cstdlib>
using namespace std;
int n, m, sum;
int fa[200005];
int siz[200005];
int tr[200005];
void add(int x, int add) {
while (x <= n) {
tr[x] += add;
x += x & -x;
}
}
int query(int k) {
int pos = 0, rnk = 0;
for (int i = 20; i >= 0; --i) {
pos |= 1 << i;
if (pos >= n || rnk + tr[pos] >= k) {
pos ^= 1 << i;
} else {
rnk += tr[pos];
}
}
return pos + 1;
}
int find(int x) {
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void merge(int x, int y) {
int fx = find(x);
int fy = find(y);
if (fx == fy) return;
add(siz[fx], -1);
add(siz[fy], -1);
fa[fx] = fy;
siz[fy] += siz[fx];
add(siz[fy], 1);
--sum;
}
int main() {
scanf("%d%d", &n, &m);
sum = n;
add(1, n);
for (int i = 1; i <= n; ++i) {
fa[i] = i;
siz[i] = 1;
}
for (int c, j, k, i = 1; i <= m; ++i) {
scanf("%d", &c);
if (!c) {
scanf("%d%d", &j, &k);
merge(j, k);
} else {
scanf("%d", &k);
printf("%d\n", query(sum - k + 1));
}
}
return 0;
}