现在的位置: 首页 > 综合 > 正文

2733: [HNOI2012]永无乡 (线段树+并查集)

2018年01月13日 ⁄ 综合 ⁄ 共 1391字 ⁄ 字号 评论关闭
#include<iostream>
#include<cstdio>
#define inf 1000000000
using namespace std;

inline int read() {
    int 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 * 10 + ch - '0';
        ch = getchar();
    }
    return x*f;
}

const int maxn = 100005, maxm = 1800000;
int n, m, k, sz, root[maxn], fa[maxn], v[maxn], id[maxn], ls[maxm], rs[maxm], sum[maxm];
char ch[2];

inline int find(int x) {
    return fa[x] == x ? x : fa[x] = find(fa[x]);
}

inline void insert(int &k, int l, int r, int val) {
    if (!k)k = ++sz;
    if (l == r) {
        sum[k] = 1;
        return;
    }
    int mid = (l + r) >> 1;
    if (val <= mid)insert(ls[k], l, mid, val);
    else insert(rs[k], mid + 1, r, val);
    sum[k] = sum[ls[k]] + sum[rs[k]];
}

inline int query(int k, int l, int r, int rank) {
    if (l == r)return l;
    int mid = (l + r) >> 1;
    if (sum[ls[k]] >= rank)return query(ls[k], l, mid, rank);
    else return query(rs[k], mid + 1, r, rank - sum[ls[k]]);
}

inline int merge(int x, int y) {
    if (!x)return y;
    if (!y)return x;
    ls[x] = merge(ls[x], ls[y]);
    rs[x] = merge(rs[x], rs[y]);
    sum[x] = sum[ls[x]] + sum[rs[x]];
    return x;
}

int main() {
    n = read();
    m = read();
    for (int i = 1; i <= n; i++)
        v[i] = read(), fa[i] = i;
    for (int i = 1; i <= m; i++) {
        int u = read(), v = read();
        int p = find(u), q = find(v);
        if (p != q)fa[p] = q;
    }
    for (int i = 1; i <= n; i++) {
        insert(root[find(i)], 1, n, v[i]);
        id[v[i]] = i;
    }
    k = read();
    for (int i = 1; i <= k; i++) {
        scanf("%s", ch);
        int x = read(), y = read();
        if (ch[0] == 'B') {
            int p = find(x), q = find(y);
            if (p != q) {
                fa[p] = q;
                root[q]=merge(root[p], root[q]);
            }
        } else {
            int p = find(x);
            if (sum[root[p]] < y) {
                puts("-1");
                continue;
            } else printf("%d\n", id[query(root[p], 1, n, y)]);
        }
    }
    return 0;
}

抱歉!评论已关闭.