码迷,mamicode.com
首页 > 其他好文 > 详细

POJ2985 The k-th Largest Group

时间:2016-09-25 18:51:06      阅读:114      评论:0      收藏:0      [点我收藏+]

标签:

题解:

并查集+树状数组+二分

注意将第k大数,转换为第tot+1-k小数,

就可以用用树状数组维护了

注意tot是动态的,在每次合并时都需要更新

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<set>
using namespace std;
using namespace std;
#define pb push_back
#define mp make_pair
#define se second
#define fs first
#define ll long long
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define ls o<<1
#define rs o<<1|1
#define SZ(x) ((int)(x).size())
#define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
typedef pair<int,int> P;
const double eps=1e-9;
const int maxn=200100;
const int N=1e9;
const int mod=1e9+7;

ll read()
{
    ll 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;
}
//-----------------------------------------------------------------------------

int fa[maxn],c[maxn],Size[maxn];
int op,a,b,n,m,tot;

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

void Union(int x,int y){
    int X=Find(x),Y=Find(y);
    if(X!=Y){
        fa[X]=Y;
        Size[Y]+=Size[X];
    }
}

int lowbit(int x){return x&-x;}

void add(int x,int v){
    while(x<=n){
        c[x]+=v;
        x+=lowbit(x);
    }
}

int sum(int x){
    int cnt=0;
    while(x){
        cnt+=c[x];
        x-=lowbit(x);
    }
    return cnt;
}

int bs(int l,int r,int goal){
    int m,tmp;
    while(l<=r){
        m=(l+r)>>1;
        if(sum(m)>=tot+1-goal){
            tmp=m;
            r=m-1;
        }
        else l=m+1;
    }
    return tmp;
}

int main(){
    n=read();m=read();
    for(int i=1;i<=n;i++){
        fa[i]=i;
        Size[i]=1;
        add(1,1);
    }
    tot=n;
    for(int i=1;i<=m;i++){
        op=read();
        if(op==0){
            a=read();b=read();
            int A=Find(a),B=Find(b);
            if(A!=B){
               tot--;
               add(Size[A],-1);
               add(Size[B],-1);
               Union(A,B);
               add(Size[B],1);
            }
        }
        else{
            a=read();
            printf("%d\n",bs(1,n,a));
        }
    }
    return 0;
}

 

POJ2985 The k-th Largest Group

标签:

原文地址:http://www.cnblogs.com/byene/p/5906427.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!