POJ-2985-The k-th Largest Group

第一次用树状数组求第k大值,其实思想就是统计比现在小的个数,然后用二分进行查找, 感觉比划分树简单多了

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=200010;
int n,m,t[maxn],p[maxn],num[maxn];
int find(int x)
{
    if(p[x]==-1)
	return x;
    return p[x]=find(p[x]);
}
int lowbit(int x)
{
    return x&(-x);
}
void Update(int i,int val)
{
    for(;i<=n;t[i]+=val,i+=lowbit(i));
}
int Sum(int i)
{
    int ans=0;
    for(;i>0;ans+=t[i],i-=lowbit(i));
    return ans;	
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
	memset(p,-1,sizeof(p));
	for(int i=1;i<=n;i++)
	    num[i]=1;
	Update(1,n);
	int res=n;
	while(m--)
	{
	    int op;
	    scanf("%d",&op);
	    if(op==0)
	    {
		int a,b;
		scanf("%d%d",&a,&b);
		int x=find(a);
		int y=find(b);
		if(x==y)
		    continue;
		Update(num[x],-1);
		Update(num[y],-1);
		num[y]+=num[x];
		Update(num[y],1);
		p[x]=y;
		res--;
	    }
	    else
	    {
		int k,l=1,r=n,ans;
		scanf("%d",&k);
		k=res-k+1;
		while(l<=r)
		{
		    int mid=(l+r)>>1;
		    if(Sum(mid)>=k)
			r=mid-1;
		    else
			l=mid+1;
		}
		printf("%d\n",l);
	    }
	}
    }
    return 0;
}


你可能感兴趣的:(二分查找,树状数组)