KiKi's K-Number
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2852
解题思路:
给你三种操作:
0 x:向容器里加入x;
1 x: 在容器内删除x,不存在x则输出“No Elment”
2 x y:在容器中找到大于x的第y个数,没有则输出“Not Find”
算法思想:树状数组。
操作1:直接add(x,1)
操作2:查找sum(x)和sum(x-1),差值为0则不存在x,反之,add(x,-1)即可删除一个x
操作3:首先查找小于等于x的个数s,则找到大于x的第y个数相当于找到第s+y小数
AC代码:
#include <bits/stdc++.h>
using namespace std ;
const int N = 100005;
int c[N];
int lowbit(int x){
return x&(-x);
}
void add(int x ,int d){//在x处加上d
for( ; x < N; x += lowbit(x))
c[x] += d ;
}
int sum(int x){//求小于等于x的个数
int ans = 0 ;
for( ; x > 0; x-=lowbit(x))
ans +=c[x] ;
return ans ;
}
int getkth1(int k){// 求第K小数模版1
int ans = 0,cnt = 0;
for(int i = 20; i >= 0; --i){
ans += 1<<i ;
if(ans>=N || cnt+c[ans]>=k)
ans -= 1<<i ;
else
cnt += c[ans] ;
}
return ans+1;
}
int getkth2(int k){//求第K小数模版2
int l = 0,r = N,mid,tmp;
while(l <= r){
mid = (l+r)>>1;
tmp = sum(mid);
if(tmp >= k)
r = mid-1;
else
l = mid+1;
}
return l;
}
int main(){
int op,m,x,k;
while(~scanf("%d",&m)){
memset(c,0,sizeof(c));
while(m--){
scanf("%d%d",&op,&x);
if(op == 0){
add(x,1);
}
else if(op == 1){
if(sum(x)-sum(x-1) == 0)
puts("No Elment!");
else
add(x,-1);
}
else{
scanf("%d",&k);
if(sum(N-1)-sum(x) < k)
puts("Not Find!");
else{
printf("%d\n",getkth2(k+sum(x)));
}
}
}
}
return 0 ;
}