【題目連結】
- 點選打開連結
【思路要點】
- 線段樹合并裸題。
- 時間複雜度\(O(NLogN+QLogN)\)。
【代碼】
#include<bits/stdc++.h> using namespace std; const int MAXN = 200005; const int MAXP = 10000005; template <typename T> void chkmax(T &x, T y) {x = max(x, y); } template <typename T> void chkmin(T &x, T y) {x = min(x, y); } template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } struct SegmentTree { struct Node { int lc, rc; int cnt; } a[MAXP]; int n, size; void init(int x) { n = x; size = 0; } void modify(int &root, int l, int r, int val) { if (root == 0) root = ++size; a[root].cnt++; if (l == r) return; int mid = (l + r) / 2; if (mid >= val) modify(a[root].lc, l, mid, val); else modify(a[root].rc, mid + 1, r, val); } int newtree(int val) { int ans = 0; modify(ans, 1, n, val); return ans; } int merge(int x, int y) { if (x == 0 || y == 0) return x + y; a[x].cnt += a[y].cnt; a[x].lc = merge(a[x].lc, a[y].lc); a[x].rc = merge(a[x].rc, a[y].rc); return x; } int query(int root, int l, int r, int k) { if (l == r) return l; int mid = (l + r) / 2; if (k <= a[a[root].lc].cnt) return query(a[root].lc, l, mid, k); else return query(a[root].rc, mid + 1, r, k - a[a[root].lc].cnt); } int query(int root, int k) { if (a[root].cnt < k) return -1; else return query(root, 1, n, k); } } ST; int n, m, q, f[MAXN], root[MAXN], ans[MAXN]; int F(int x) { if (f[x] == x) return x; else return f[x] = F(f[x]); } int main() { read(n), read(m); ST.init(n); for (int i = 1; i <= n; i++) { int x; read(x); ans[x] = f[i] = i; root[i] = ST.newtree(x); } for (int i = 1; i <= m; i++) { int x, y; read(x), read(y); if (F(x) != F(y)) { root[F(y)] = ST.merge(root[F(x)], root[F(y)]); f[F(x)] = F(y); } } read(q); for (int i = 1; i <= q; i++) { char opt; int x, y; scanf("\n%c%d%d", &opt, &x, &y); if (opt == 'B') { if (F(x) != F(y)) { root[F(y)] = ST.merge(root[F(x)], root[F(y)]); f[F(x)] = F(y); } } else { int tmp = ST.query(root[F(x)], y); if (tmp == -1) writeln(tmp); else writeln(ans[tmp]); } } return 0; }