(HDU - 2852)KiKi's K-Number

(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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值