rt,平衡树的操作没有问题,不知道那里写挂了。
https://www.luogu.com.cn/record/97113161
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
struct node {
int val, ls, rs, cnt, tot, siz, tsiz;
} tree[N];
int cnt, tot, cur[N];
queue<int> delq;
int new_node() {
if (delq.empty()) return ++ cnt;
int res = delq.front(); delq.pop();
return res;
}
struct ScapegoatTree {
const double alpha = 0.6666;
int siz, rt;
ScapegoatTree() { siz = rt = 0; }
bool isBad(int u) {
return tree[u].cnt && (alpha * tree[u].tot <= double(max(tree[tree[u].ls].tot, tree[tree[u].rs].tot))
|| double(tree[u].tsiz) < alpha * tree[u].tot);
}
void push_up(int u) {
tree[u].tot = tree[tree[u].ls].tot + tree[tree[u].rs].tot + 1;
tree[u].siz = tree[tree[u].ls].siz + tree[tree[u].rs].siz + tree[u].cnt;
tree[u].tsiz = tree[tree[u].ls].tsiz + tree[tree[u].rs].tsiz + bool(tree[u].cnt);
}
void dfs(int u) {
if (!u) return;
dfs(tree[u].ls);
if (tree[u].cnt) cur[tot ++] = u;
dfs(tree[u].rs);
}
int build(int l, int r) {
int mid = (l + r) >> 1;
if (l >= r) return 0;
tree[cur[mid]].ls = build(l, mid);
tree[cur[mid]].rs = build(mid + 1, r);
push_up(cur[mid]);
return cur[mid];
}
inline void rebuild(int& u) {
tot = 0, dfs(u);
if (u == rt) rt = u = build(0, tot);
else u = build(0, tot);
}
int insert(int u, int val) {
if (!u) {
u = new_node();
if (!rt) rt = u;
tree[u].val = val;
tree[u].siz = tree[u].cnt = 1;
} else {
if (tree[u].val == val) tree[u].cnt ++;
if (val < tree[u].val) tree[u].ls = insert(tree[u].ls, val);
if (val > tree[u].val) tree[u].rs = insert(tree[u].rs, val);
push_up(u);
if (isBad(u)) rebuild(u);
}
return u;
}
void del(int u, int val) {
if (!u) return;
if (tree[u].val == val) tree[u].cnt --;
if (val < tree[u].val) del(tree[u].ls, val);
if (val > tree[u].val) del(tree[u].rs, val);
push_up(u);
}
int query(int u, int val) {
if (!u) return 0;
if (tree[u].val == val) return tree[tree[u].ls].siz;
if (val < tree[u].val) return query(tree[u].ls, val);
return query(tree[u].rs, val) + tree[tree[u].ls].siz + tree[u].cnt;
}
int Kth(int u, int k) {
if (!u) return -1;
if (tree[tree[u].ls].siz >= k) return Kth(tree[u].ls, k);
if (tree[tree[u].ls].siz + tree[u].cnt >= k) return tree[u].val;
return Kth(tree[u].rs, k - tree[tree[u].ls].siz - tree[u].cnt);
}
void merge(int u) {
if (!u) return;
for (int i = 1; i <= tree[u].cnt; i ++)
insert(rt, tree[u].val), delq.push(u);
merge(tree[u].ls), merge(tree[u].rs);
}
void print(int u) {
if (!u) return;
print(tree[u].ls);
print(tree[u].rs);
cout << tree[u].val << ' ' << tree[u].cnt << '\n';
}
} T[N];
int n, m, q, u, v, f[N], rk[N];
char opt;
int find(int u) {
return f[u] == u ? u : f[u] = find(f[u]);
}
void merge(int u, int v) {
int fu = find(u), fv = find(v);
if (fu == fv) return;
if (T[fu].siz < T[fv].siz) swap(fu, fv);
T[fu].merge(T[fv].rt), f[fv] = fu;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i ++)
cin >> u, rk[u] = i, T[i].insert(T[i].rt, u), f[i] = i;
for (int i = 1; i <= m; i ++)
cin >> u >> v, merge(u, v);
cin >> q;
for (int i = 1; i <= q; i ++) {
cin >> opt >> u >> v;
if (opt == 'Q') {
u = find(u);
int res = T[u].Kth(T[u].rt, v);
cout << (~res ? rk[res] : res) << '\n';
}
if (opt == 'B') merge(u, v);
if (opt == 'C') u = find(u), T[u].print(T[u].rt);
}
return 0;
}