zoukankan      html  css  js  c++  java
  • HDU 2852(树状数组plus二分)

                                 KiKi's K-Number

      Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
      Total Submission(s): 4847    Accepted Submission(s): 2228

    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 <e <100000), means press element e into Container.

    If p is 1, then there will be an integer e (0 <e <100000), indicated that delete the element e from the container  

    If p is 2, then there will be two integers a and k (0 <a <100000, 0 <k <10000),means the inquiries, the element is greater than a, and the k-th larger number.
     
    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!
    __________________________________________________
    题目大意:对一个集合进行n种操作
    1>,向集合中增加一个数
    2>,删除集合中的一个数
    3>,查询集合中第k个比a大的数
    解题思路:
    用树状数组来解决,num[i]表示小于i的元素有几个,因此对于1和2直接对数组进行修改即可,但是对于3我们可以
    采用二分的方法进行查找每次查找看一下sum(mid)-sum(a)与k的关系来进行下一次操作,依此进行即可,小于mid的元素的个数减去
    小于a的个数即为大于a的元素的个数,用此值与k进行比较即可
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define maxn (int)1e5+5
    #include<cstring>
    typedef long long ll;
    int lowbit(int x)
    {
        return x&(-x);
    }
    ll n,c[maxn],vis[maxn];  //c tong ji he zhi c1 tong ji ge shu
    void add(ll x,ll num)
    {
        while(x<=maxn)
        {
            c[x]+=num;
            x+=x&(-x); 
        }
    }
    ll sum(ll x)
    {
        ll ans=0;
        while(x)
        {
            ans+=c[x];
            x-=x&(-x);
        }
        return ans;
    }
    ll cal(ll r,ll l)
    {
        return sum(r)-sum(l);
    }
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            memset(c,0,sizeof(c));
            memset(vis,0,sizeof(vis));
            while(n--)
            {
                int a;
                scanf("%lld",&a);
                if(a==0)
                {
                    int b;
                    scanf("%lld",&b);
                    vis[b]++;
                    add(b,1);
                }
                else if(a==1)
                {
                    int b;
                    scanf("%lld",&b);
                    if(vis[b]==0)
                    {
                        cout<<"No Elment!"<<endl; 
                    }
                    else
                    {
                        vis[b]--;
                        add(b,-1);
                    }
                }
                else
                {
                    int a,b;
                    cin>>a>>b;
                    int l=a,r=100000;
                    int mid,ret=-1;
                    while(l<=r)
                    {
                        mid=(l+r)>>1;
                        if(cal(mid,a)>=b)
                        {
                            r=mid-1;
                            ret=mid;
                        }
                        else l=mid+1;
                    }
                    if(ret==-1) cout<<"Not Find!"<<endl;
                    else cout<<ret<<endl;
                }
            }
        } 
        return 0;
    }
     
  • 相关阅读:
    剑指Offer_#7_重建二叉树
    剑指Offer_#6_从尾到头打印链表
    剑指Offer_#5_替换空格
    剑指Offer_#4_二维数组中的查找
    Redis详解(十三)- Redis布隆过滤器
    Redis详解(十二)- 缓存穿透、缓存击穿、缓存雪崩
    Redis详解(十一)- 过期删除策略和内存淘汰策略
    Redis详解(十)- 集群模式详解
    Redis详解(九)- 哨兵(Sentinel)模式详解
    Redis详解(八)- 主从复制
  • 原文地址:https://www.cnblogs.com/tombraider-shadow/p/11157826.html
Copyright © 2011-2022 走看看