专栏文章
3324 永无乡
个人记录参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miqmrgqo
- 此快照首次捕获于
- 2025/12/04 07:20 3 个月前
- 此快照最后确认于
- 2025/12/04 07:20 3 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int n, m, q, f[N];
int root[N], tot;
int ls[N*20], rs[N*20], id[N*20], sum[N*20];
// id:节点编号, sum:重要度的出现次数之和
// 时间空间复杂度为nlogn
int find(int x){
if(x == f[x])
return x;
return f[x] = find(f[x]);
}
void pushup(int p){
sum[p] = sum[ls[p]] + sum[rs[p]];
}
int update(int u, int pl, int pr, int p, int i){
if(!u) u = ++tot;
//sum[u] ++; //如果sum[u]++写在这里,就可以不需要pushup操作。
if(pl == pr){
id[u] = i;
sum[u] ++;
return u;
}
int mid = (pl + pr) / 2;
if(p <= mid)
ls[u] = update(ls[u], pl, mid, p, i);
else
rs[u] = update(rs[u], mid+1, pr, p, i);
pushup(u);
return u;
}
int merge(int x, int y, int pl, int pr){
if(!x || !y) return x + y;
if(pl == pr){
sum[x] += sum[y];
return x;
}
int mid = (pl + pr) / 2;
ls[x] = merge(ls[x], ls[y], pl, mid);
rs[x] = merge(rs[x], rs[y], mid + 1, pr);
pushup(x);
return x;
}
int query(int u, int pl, int pr, int k){
if(pl == pr) return id[u];
int ans = 0;
int mid = (pl + pr) / 2;
if(k <= sum[ls[u]]) ans = query(ls[u], pl, mid, k);
else ans = query(rs[u], mid+1, pr, k-sum[ls[u]]);
return ans;
}
int main(){
int x, y;
scanf("%d%d",&n, &m);
for(int i=1; i<=n; i++){
f[i] = i;
scanf("%d",&x);
root[i] = update(root[i], 1, n, x, i);
}
for(int i=1; i<=m; i++){
scanf("%d%d",&x, &y);
x = find(x);
y = find(y);
if(x == y) continue;
f[y] = x;
root[x] = merge(root[x], root[y], 1, n);
}
scanf("%d",&q);
while(q--){
char ch[5];
scanf("%s", ch);
if(ch[0] == 'B'){
scanf("%d%d",&x, &y);
x = find(x);
y = find(y);
if(x == y) continue;
f[y] = x;
root[x] = merge(root[x], root[y], 1, n);
}
else{
scanf("%d%d",&x, &y);
x = find(x);
int ans = query(root[x], 1, n, y);
ans = ans? ans:-1;
printf("%d\n", ans);
}
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...