题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2852
题意:给三种操作,
(1)加入一个数e;
(2)删除一个数,如果这个数不存在,输出No Elment!
(3)查询比a大的第k个数,如果这个数不存在,输出Not Find!,否则,输出这个数
思路:前两种操作都是树状数组的单点更新,最后一个操作相当于在一个单调不减的数组里查找第k个比a大的数,所以可以考虑使用二分逼近
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e5+7;
int c[maxn];
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int val)
{
for(int i=x;i<=maxn;i+=lowbit(i))
{
c[i]+=val;
}
}
int query(int x)
{
int ans=0;
for(int i=x;i>0;i-=lowbit(i))
{
ans+=c[i];
}
return ans;
}
int vis[maxn];
int Find(int k)
{
int ans=0,l=1,r=maxn;
while(l<=r)
{
int mid=(l+r+1)>>1;
if(query(mid)>=k) ans=mid,r=mid-1;
else l=mid+1;
}
return ans;
}
int main()
{
int q;
while(~scanf("%d",&q))
{
memset(vis,0,sizeof(vis));
memset(c,0,sizeof(c));
while(q--)
{
int opt;
scanf("%d",&opt);
if(opt==0)
{
int x;
scanf("%d",&x);
vis[x]++;
update(x,1);
}
else if(opt==1)
{
int x;
scanf("%d",&x);
if(vis[x]==0)
{
printf("No Elment!\n");
}
else
{
vis[x]--;
update(x,-1);
}
}
else
{
int a,k;
scanf("%d%d",&a,&k);
if(query(maxn)-query(a)<k) printf("Not Find!\n");
else
{
printf("%d\n",Find(query(a)+k));
}
}
}
}
return 0;
}