pku2985 The k-th Largest Group

 

题意:初始化状态为N个含单一元素的集合,动态合并任意两个集合,查询第ith大的集合的大小

分析:以虚二叉树做辅助结构找出第ith大的集合的大小

 

#include <iostream>
#include 
<algorithm>
using namespace std;

#define MAXN 200001

int v[MAXN],N,M,pnt[MAXN],son[3*MAXN];
//v[i]第i只猫所在组的猫的数量,范围在1~N之间;son[u]表示以结点u为根的子树的结点数

void insert(int num,int k){
    
int l=1,r=N,m,u=1;
    
while(l<r){
        m
=(l+r)/2;
        son[u]
+=k;
        
if(num<=m){
            r
=m;
            u
=u*2;
        }
        
else{
            l
=m+1;
            u
=u*2+1;
        }
    }
    son[u]
+=k;
}

int find(int ith){
    
int l=1,r=N,u=1,m;
    
while(l<r){
        m
=(l+r)/2;
        
if(son[2*u+1]>=ith){
            l
=m+1;
            u
=u*2+1;
        }
        
else{
            ith
-=son[2*u+1];
            r
=m;
            u
=u*2;
        }
    }
    
return l;
}



void init(){
    
int i;
    
for(i=1;i<=N;i++){
        pnt[i]
=i;
        v[i]
=1;
        insert(v[i],
1);
    }
}

int fs(int i){
    
if(pnt[i]==i)
        
return i;
    pnt[i]
=fs(pnt[i]);
    
return pnt[i];
}



int main(){
    
int q,a,b,x,y,ith;
    
while(scanf("%d%d",&N,&M)!=EOF){
        init();
        
while(M--){
            scanf(
"%d",&q);
            
if(q==0){
                scanf(
"%d%d",&a,&b);
                x
=fs(a);
                y
=fs(b);
                
if(x!=y){
                    pnt[x]
=y;                    
                    insert(v[x],
-1);
                    insert(v[y],
-1);
                    v[y]
+=v[x];
                    insert(v[y],
1);
                }
            }
            
else{
                scanf(
"%d",&ith);
                printf(
"%d\n",find(ith));
            }
        }
    }
    
return 0;
}

posted @ 2008-11-05 00:37  Beetlebum  阅读(288)  评论(0编辑  收藏  举报