POJ2985 The k-th Largest Group

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ2985 The k-th Largest Group相关的知识,希望对你有一定的参考价值。

题解:

并查集+树状数组+二分

注意将第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的主要内容,如果未能解决你的问题,请参考以下文章

POJ--2985 The k-th Largest Group(第K大组,带权并查集+树状数组+二分)

POJ--2985 The k-th Largest Group(第K大组,带权并查集+树状数组+二分)

hdu 2985 The k-th Largest Group 树状数组求第K大

POJ 2761 Feed the dogs (主席树)(K-th 值)

poj2985

POJ2985 并查集+线段树 求第k大的数