(HDU - 2852)KiKi’s K-Number
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4230 Accepted Submission(s): 1917
Problem Description
For the k-th number, we all should be very familiar with it. Of course,to kiki it is also simple. Now Kiki meets a very similar problem, kiki wants to design a container, the container is to support the three operations.
Push: Push a given element e to container
Pop: Pop element of a given e from container
Query: Given two elements a and k, query the kth larger number which greater than a in container;
Although Kiki is very intelligent, she can not think of how to do it, can you help her to solve this problem?
Input
Input some groups of test data ,each test data the first number is an integer m (1 <= m <100000), means that the number of operation to do. The next m lines, each line will be an integer p at the beginning, p which has three values:
If p is 0, then there will be an integer e (0
Output
For each deletion, if you want to delete the element which does not exist, the output “No Elment!”. For each query, output the suitable answers in line .if the number does not exist, the output “Not Find!”.
Sample Input
5
0 5
1 2
0 6
2 3 2
2 8 1
7
0 2
0 2
0 4
2 1 1
2 1 2
2 1 3
2 1 4
Sample Output
No Elment!
6
Not Find!
2
2
4
Not Find!
题目大意:有一种容器支持三种操作:p==0,将数e加入容器中;p==1,将数e从容器中删除,如果没有这个数,就输出”No Elment!”;p==2,在容器中找大于a的第k大的数,如果找不到就输出“Not Find!”。
思路:可以用树状数组维护这样的一个容器,加入数e就是update(e,1);删除数e就是update(e,-1),删除时先判断getsum(e)是否等于getsum(e-1),如果相等说明在容器中没有数e这个数,应该输出“No Elment!”;查找大于a的第k大数时可以转化为大于1的第getsum(a)+k大数,这个可以用二分来找。
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const int maxn=100005;
int c[maxn];
int lowbit(int x)
{
return x&-x;
}
void update(int x,int d)
{
for(;x<maxn;x+=lowbit(x)) c[x]+=d;
}
LL getsum(int x)
{
LL sum=0;
for(;x>0;x-=lowbit(x)) sum+=(LL)c[x];
return sum;
}
LL bs(int a,int k)
{
LL x=getsum(a);
x+=k;
int lo=1,hi=maxn-1,mid;
int ans;
while(lo<=hi)
{
mid=(lo+hi)>>1;
if(getsum(mid)>=x)
{
ans=mid;
hi=mid-1;
}
else lo=mid+1;
}
return ans;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(c,0,sizeof(c));
while(n--)
{
int p;
scanf("%d",&p);
if(p==0)
{
int e;
scanf("%d",&e);
update(e,1);
}
else if(p==1)
{
int e;
scanf("%d",&e);
if(getsum(e)==getsum(e-1)) printf("No Elment!\n");
else update(e,-1);
}
else
{
int a,k;
scanf("%d%d",&a,&k);
if((getsum(maxn-1)-getsum(a))<k) printf("Not Find!\n");
else printf("%lld\n",bs(a,k));
}
}
}
return 0;
}