HDU 2852-KiKi’s K-Number
题目原址
[http://acm.hdu.edu.cn/showproblem.php?pid=2852]
题意
要实现一种容器,可以向里面加入一个数字,弹出一个数字,查询在容器内第k个比a大的元素(这里可能会有误解,第一个比a大的元素应该是所有比a大的元素中最小的那个)
我们要用的就是权值树状数组,c[i]表示的是小于等于I的元素数量有多少个。
求比a大k的元素就用二分就可以了。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
ll c[maxn];
int a[maxn];
int lowbit(int x){
return x&-x;
}
void upd(int x,int v){
a[x]+=v;
for(int i=x;i<maxn;i+=lowbit(i))
c[i]+=v;
}
ll qry(int x){
ll ans=0;
for(int i=x;i;i-=lowbit(i))
ans+=c[i];
return ans;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif // LOCAL
int m;
while(~scanf("%d",&m)){
memset(c,0,sizeof(c));
memset(a,0,sizeof(a));
while(m--){
int p,e,k;
scanf("%d",&p);
if(p==0){
scanf("%d",&e);
upd(e,1);
}
else if(p==1){
scanf("%d",&e);
if(a[e])
upd(e,-1);
else
printf("No Elment!\n");
}
else if(p==2){
scanf("%d%d",&e,&k);
if(qry(maxn-4)-qry(e)<k)
printf("Not Find!\n");
else{
int l=1,r=maxn-1,mid;
int ans=0;
while(l<=r){
mid=(l+r)>>1;
if(qry(mid)-qry(e)>=k){
r=mid-1;
ans=mid;
}
else
l=mid+1;
}
printf("%d\n",ans);
}
}
}
}
}