hrbust2371權值線段樹+並查集

題目鏈接:

http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2371

講解視頻:https://www.bilibili.com/video/av16552942?from=search&seid=6401426487448027126

題解:權值線段樹+並查集很水,衆人皆知。

#include <bits/stdc++.h>

using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int maxn = 1e5 + 7;
int A[maxn<<2], son[maxn];
int n, q, par[maxn];

void pushup(int rt)
{
    A[rt] = A[rt<<1] + A[rt<<1|1];
}
void update(int p, int v, int l, int r, int rt) //將p這個值插入 v = 1 or -1
{
    A[rt] += v;
    if(l == r) return ;
    int mid = (l + r) >> 1;
    if(p <= mid) update(p, v, lson);
    else update(p, v, rson);
    pushup(rt);
}
int kth(int k, int l, int r, int rt) // k_th_element
{
    if(l == r) return l;
    int mid = (l + r) >> 1;
    if(A[rt<<1] >= k) return kth(k, lson);
    return kth(k-A[rt<<1], rson);
}
int Rank(int p, int l, int r, int rt) // query p's rank in array => how many number in [1,p-1]
{
    if(r < p) return A[rt];
    //r >= p;
    int mid = (l + r) >> 1;
    int res = 0;
    res += Rank(p, lson);
    if(mid + 1 < p) res += Rank(p, rson);
    return res;
}
int Find_pre(int l, int r, int rt)
{
    if(l == r) return l;
    int mid = (l + r) >> 1;
    if(A[rt<<1|1]) return Find_pre(rson);
    return Find_pre(lson);
}
int Pre(int p, int l, int r, int rt)
{
    int mid = (l + r) >> 1, res;
    if(r < p) {
        if(A[rt]) return Find_pre(lson);
        return 0;
    }
    if(mid + 1 < p && A[rt<<1|1] && (res = Pre(p, rson))) return res;
    return Pre(p, lson);
}

int Find_nxt(int l, int r, int rt)
{
    if(l == r) return l;
    int mid = (l + r) >> 1;
    if(A[rt<<1]) return Find_nxt(lson);
    return Find_nxt(rson);
}
int Nxt(int p, int l, int r, int rt)
{
    int mid = (l + r) >> 1, res;
    if(l > p) {
        if(A[rt]) return Find_nxt(lson);
        return 0;
    }
    if(p < mid && A[rt<<1] && (res = Nxt(p, lson))) return res;
    return Nxt(p, rson);
}
void build(int l, int r, int rt)
{
    A[rt] = 0;
    if(l == r) return;
    int mid=(l+r)/2;
    build(lson);
    build(rson);
}

int find(int x)
{
    return x==par[x]?x:par[x]=find(par[x]);
}
int main()
{
    int T;
    scanf("%d", &T);
    while(T --) {
        scanf("%d %d", &n, &q);
        build(1, n, 1);
        for(int i = 1;i <= n;i ++) update(1,1,1,n,1),par[i] = i, son[i] = 1;
        int all = n;
        int opt;
        while(q --) {
            scanf("%d", &opt);
            if(opt == 1) {
                int x, y; // x eat y
                scanf("%d %d", &x, &y);
                x = find(x);
                y = find(y);
                if(x != y) {
                    -- all;
                    par[y] = x;
                    update(son[x], -1, 1, n, 1);
                    update(son[y], -1, 1, n, 1);
                    son[x] += son[y];
                    son[y] = 0;
                    update(son[x], 1, 1, n, 1);
                }
            } else {
                int k;
                scanf("%d", &k);
                if(k > all) {
                    puts("-1");
                    continue;
                } else {
                    k = all - k + 1;
//                    printf("%d\n", k);
                    printf("%d\n", kth(k, 1, n, 1));
                }
            }
        }
    }
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章