POJ2985 The k-th Largest Group(平衡树查询第K大)

来源:互联网 发布:孟加拉地区代码数据库 编辑:程序博客网 时间:2024/06/05 02:04

传送门
平衡树查询第k大的裸题,用并查集来维护一下哪些猫是一组的就可以了。查询第k大要维护size域,保存一个节点下面的字数的大小,更新的时候从下边更新。

#include<cstdio>#define MAXN 200005struct SBT {    int v, sz, ch[2], cnt;} t[MAXN];int n, m, cnt, root;#define Upd(k) {\    t[k].sz = t[t[k].ch[0]].sz + t[t[k].ch[1]].sz + t[k].cnt;\}void rot(int &k, bool f) {    int p = t[k].ch[f]; t[k].ch[f] = t[p].ch[!f]; t[p].ch[!f] = k;    Upd(k); Upd(p); k = p;}inline void mt(int &k,bool f){    if(!k) return;    if(t[t[k].ch[f^1]].sz < t[t[t[k].ch[f]].ch[f]].sz) rot(k, f);    else if(t[t[k].ch[f^1]].sz < t[t[t[k].ch[f]].ch[f^1]].sz) { rot(t[k].ch[f], f^1); rot(k, f); }    else return;    mt(t[k].ch[f],f);    mt(k,f);}void Ins(int &k, int x) {    if(!k) {k = ++ cnt; t[k].sz = t[k].cnt = 1; t[k].v = x; return; }    ++ t[k].sz;    if(t[k].v == x) {++ t[k].cnt; return;}    Ins(t[k].ch[t[k].v < x], x);    mt(k, t[k].v < x);}int Del(int &k, int x) {    if(!k) return k;    int tmp;    if(t[k].v == x) {        if(t[k].cnt > 1) {-- t[k].cnt; --t[k].sz; return k;}        else if(!(t[k].ch[0]*t[k].ch[1])) {k = t[k].ch[0]+t[k].ch[1];}        else { tmp = Del(t[k].ch[0], x+1); t[k].cnt = t[tmp].cnt; t[k].v = t[tmp].v; Upd(k); return k; }    }    else if((t[k].v < x && !t[k].ch[1]) || (t[k].v > x && ! t[k].ch[0])) { tmp = k; k = t[k].ch[0]; Upd(k); return tmp; }    else tmp = Del(t[k].ch[t[k].v < x], x);    Upd(k); return tmp;}int Kth(int k,int x) {              //查询第k大    if(x<=t[t[k].ch[1]].sz)        return Kth(t[k].ch[1],x);    else if(x>t[t[k].ch[1]].sz+t[k].cnt)        return Kth(t[k].ch[0],x-t[t[k].ch[1]].sz-t[k].cnt);    else return t[k].v;}char c, f;inline void GET(int &n) {    n = 0; f = 1;    do {c = getchar(); if(c == '-') f = -1;} while(c > '9' || c < '0');    while(c >= '0' && c <= '9') {n=n*10+c-'0';c=getchar();}    n *= f;}/**********************并查集相关********************/int fa[MAXN], num[MAXN];int Q(int x) {    return x == fa[x] ? x : (fa[x] = Q(fa[x]));}void Union(int a, int b) {    int af = Q(a), bf = Q(b);    if(af == bf) return;    Del(root, num[af]); Del(root, num[bf]);    fa[bf] = af; num[af] += num[bf];    Ins(root, num[af]);}/***************************************************/int main() {    GET(n); GET(m);    int t1, t2, t3;    Ins(root, 0x7f7f7f7f); Ins(root, -0x7f7f7f7f);    for(int i = 1; i <= n; ++ i) fa[i] = i, num[i] = 1, Ins(root, 1);    while(m --) {        GET(t1); GET(t2);        if(t1) printf("%d\n", Kth(root, t2+1));        else {            GET(t3); Union(t2, t3);        }    }}
0 0