洛谷 P3224 [HNOI2012]永無鄉
阿新 • • 發佈:2020-11-24
傳送門
#include <bits/stdc++.h> using namespace std; using ll = long long; using p = pair<int, int>; const int maxn(2e6 + 10); int idx, root[maxn], pre[maxn]; struct node { int id; int val, siz; int fa, ch[2]; } tree[maxn]; template<typename T = int> inline const T read() { T x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); } return x * f; } template<typename T> inline void write(T x, bool ln) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) write(x / 10, false); putchar(x % 10 + '0'); if (ln) putchar(10); } inline int find(int cur) { return pre[cur] == cur ? cur : pre[cur] = find(pre[cur]); } inline int new_node(int val, int id) { ++idx; tree[idx].val = val; tree[idx].id = id; tree[idx].siz = 1; return idx; } inline int get_rel(int cur, int fa) { return tree[fa].ch[1] == cur; } inline void push_up(int cur) { tree[cur].siz = tree[tree[cur].ch[0]].siz + tree[tree[cur].ch[1]].siz + 1; } inline void connect(int cur, int fa, bool rel) { tree[cur].fa = fa; tree[fa].ch[rel] = cur; } inline void rotate(int cur) { int fa = tree[cur].fa; int gf = tree[fa].fa; bool rel = get_rel(cur, fa); connect(tree[cur].ch[rel ^ 1], fa, rel); connect(cur, gf, get_rel(fa, gf)); connect(fa, cur, rel ^ 1); push_up(fa); push_up(cur); } inline void splaying(int cur, int top, int& rt) { while (tree[cur].fa not_eq top) { int fa = tree[cur].fa; int gf = tree[fa].fa; if (gf not_eq top) { get_rel(cur, fa) ^ get_rel(fa, gf) ? rotate(cur) : rotate(fa); } rotate(cur); } if (not top) { rt = cur; } } inline void insert(int val, int id, int& rt) { int cur = rt, fa = 0; while (cur) { fa = cur; cur = tree[cur].ch[val > tree[cur].val]; } cur = new_node(val, id); connect(cur, fa, val > tree[fa].val); splaying(cur, 0, rt); } inline int get_id(int rank, int rt) { int cur = rt; while (cur) { if (tree[tree[cur].ch[0]].siz >= rank) { cur = tree[cur].ch[0]; } else if (tree[tree[cur].ch[0]].siz + 1 == rank) { break; } else { rank -= tree[tree[cur].ch[0]].siz + 1; cur = tree[cur].ch[1]; } } return tree[cur].id; } inline void dfs(int u, int& v) { if (not u) return; dfs(tree[u].ch[0], v); dfs(tree[u].ch[1], v); insert(tree[u].val, tree[u].id, v); } inline void merge(int u, int v) { u = find(u); v = find(v); if (u not_eq v) { if (tree[root[u]].siz > tree[root[v]].siz) { swap(u, v); } dfs(root[u], root[v]); pre[u] = v; } } int main() { #ifdef ONLINE_JUDGE #else freopen("input.txt", "r", stdin); #endif int n = read(), m = read(); for (int i = 1; i <= n; ++i) { pre[i] = root[i] = new_node(read(), i); } while (m--) { int u = read(), v = read(); merge(u, v); } int q = read(); while (q--) { char op[2]; scanf("%s", op); int x = read(), k = read(); if (*op == 'Q') { int rt = root[find(x)]; if (tree[rt].siz < k) { write(-1, true); } else { write(get_id(k, rt), true); } } else { merge(x, k); } } return 0; }