題目鏈接:
http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2371
講解視頻:https://www.bilibili.com/video/av16552942?from=search&seid=6401426487448027126
題解:權值線段樹+並查集很水,衆人皆知。
#include <bits/stdc++.h>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int maxn = 1e5 + 7;
int A[maxn<<2], son[maxn];
int n, q, par[maxn];
void pushup(int rt)
{
A[rt] = A[rt<<1] + A[rt<<1|1];
}
void update(int p, int v, int l, int r, int rt) //將p這個值插入 v = 1 or -1
{
A[rt] += v;
if(l == r) return ;
int mid = (l + r) >> 1;
if(p <= mid) update(p, v, lson);
else update(p, v, rson);
pushup(rt);
}
int kth(int k, int l, int r, int rt) // k_th_element
{
if(l == r) return l;
int mid = (l + r) >> 1;
if(A[rt<<1] >= k) return kth(k, lson);
return kth(k-A[rt<<1], rson);
}
int Rank(int p, int l, int r, int rt) // query p's rank in array => how many number in [1,p-1]
{
if(r < p) return A[rt];
//r >= p;
int mid = (l + r) >> 1;
int res = 0;
res += Rank(p, lson);
if(mid + 1 < p) res += Rank(p, rson);
return res;
}
int Find_pre(int l, int r, int rt)
{
if(l == r) return l;
int mid = (l + r) >> 1;
if(A[rt<<1|1]) return Find_pre(rson);
return Find_pre(lson);
}
int Pre(int p, int l, int r, int rt)
{
int mid = (l + r) >> 1, res;
if(r < p) {
if(A[rt]) return Find_pre(lson);
return 0;
}
if(mid + 1 < p && A[rt<<1|1] && (res = Pre(p, rson))) return res;
return Pre(p, lson);
}
int Find_nxt(int l, int r, int rt)
{
if(l == r) return l;
int mid = (l + r) >> 1;
if(A[rt<<1]) return Find_nxt(lson);
return Find_nxt(rson);
}
int Nxt(int p, int l, int r, int rt)
{
int mid = (l + r) >> 1, res;
if(l > p) {
if(A[rt]) return Find_nxt(lson);
return 0;
}
if(p < mid && A[rt<<1] && (res = Nxt(p, lson))) return res;
return Nxt(p, rson);
}
void build(int l, int r, int rt)
{
A[rt] = 0;
if(l == r) return;
int mid=(l+r)/2;
build(lson);
build(rson);
}
int find(int x)
{
return x==par[x]?x:par[x]=find(par[x]);
}
int main()
{
int T;
scanf("%d", &T);
while(T --) {
scanf("%d %d", &n, &q);
build(1, n, 1);
for(int i = 1;i <= n;i ++) update(1,1,1,n,1),par[i] = i, son[i] = 1;
int all = n;
int opt;
while(q --) {
scanf("%d", &opt);
if(opt == 1) {
int x, y; // x eat y
scanf("%d %d", &x, &y);
x = find(x);
y = find(y);
if(x != y) {
-- all;
par[y] = x;
update(son[x], -1, 1, n, 1);
update(son[y], -1, 1, n, 1);
son[x] += son[y];
son[y] = 0;
update(son[x], 1, 1, n, 1);
}
} else {
int k;
scanf("%d", &k);
if(k > all) {
puts("-1");
continue;
} else {
k = all - k + 1;
// printf("%d\n", k);
printf("%d\n", kth(k, 1, n, 1));
}
}
}
}
return 0;
}