第一次用树状数组求第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;
}