sb题
合并:并查集+线段树启发式合并,注意动态开点
查询:直接查对应线段树的K大。
时间复杂度 O(qlog2n)
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a,_=b;i<=_;i++)
#define per(i,a,b) for(int i=a,_=b;i>=_;i--)
#define maxn 200007
#define maxs 3000007
inline int rd() {
char c = getchar();
while (!isdigit(c)) c = getchar() ; int x = c - '0';
while (isdigit(c = getchar())) x = x * 10 + c - '0';
return x;
}
typedef int arr[maxn];
typedef int seg[maxs];
arr a , h , rt , fa , rk;
seg lc , rc , cnt , pool;
int s_tot , tot , n , m;
inline int newnode() {
/*if (s_tot) return pool[s_tot --]; else return ++ tot;*/
return ++ tot;
}
inline void delnode(int t) {
cnt[t] = 0 , lc[t] = rc[t] = 0;
pool[s_tot ++] = t;
}
void _merge(int pr , int&nr) {
if (!pr) return;
if (!nr) nr = newnode();
cnt[nr] += cnt[pr];
if (cnt[lc[pr]]) _merge(lc[pr] , lc[nr]);
if (cnt[rc[pr]]) _merge(rc[pr] , rc[nr]);
delnode(pr);
}
int find(int u) { return u == fa[u] ? u : fa[u] = find(fa[u]); }
inline void merge(int u , int v) {
u = find(u) , v = find(v);
if (u == v) return ;
if (rk[u] > rk[v]) swap(u , v);
fa[u] = v;
if (rk[u] == rk[v]) rk[v] ++;
_merge(rt[u] , rt[v]);
rt[u] = 0;
}
void update(int&u , int l , int r , int v) {
if (!u) u = newnode();
cnt[u] ++;
if (l == r) return ;
int m = (l + r) >> 1;
if (v <= m)
update(lc[u] , l , m , v);
else
update(rc[u] , m + 1 , r , v);
}
void input() {
n = rd() , m = rd();
rep (i , 1 , n) a[i] = rd();
rep (i , 1 , n) h[a[i]] = i;
rep (i , 1 , n) fa[i] = i;
rep (i , 1 , n) rk[i] = 1;
rep (i , 1 , n) update(rt[i] , 1 , n , a[i]);
rep (i , 1 , m)
merge(rd() , rd());
}
int kth(int u , int l , int r , int k) {
int t = 0;
if (cnt[u] < k) return -1;
while (l < r) {
int m = (l + r) >> 1;
if (cnt[lc[u]] >= k)
u = lc[u] , r = m;
else
k -= cnt[lc[u]] , u = rc[u] , l = m + 1;
}
return h[l];
}
void query(int u , int k) {
u = find(u);
int t = kth(rt[u] , 1 , n , k);
printf("%d\n" , t);
}
void solve() {
char cmd[2];
rep (q , 1 , rd()) {
scanf("%s" , cmd);
int u = rd() , v = rd();
if (cmd[0] == 'Q')
query(u , v);
else
merge(u , v);
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("data.txt" , "r" , stdin);
// freopen("data.out" , "w" , stdout);
#endif
input();
solve();
return 0;
}