HDU 2852 KiKi's K-Number(树状数组+二分)

KiKi‘s K-Number

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 2598    Accepted Submission(s): 1199

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!

Source

0 表示添加节点

1表示删除节点

2 找到比b大的第k大的数

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#define init(a) memset(a,0,sizeof(a))
using namespace std;
#define MAX INT_MAX
#define MIN INT_MIN
#define LL __int64
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 300010;
const int maxm = 100010;
using namespace std;
int c[maxn];
int hash[maxm];
int lowbit(int x)
{
    return x&(-x);
}
void add(int x,int w)
{
    while(x<=maxn)
    {
        c[x]+=w;
        x+=lowbit(x);
    }
}
int sum(int i)
{
    int s=0;
    while(i>0)
    {
        s += c[i];
        i =i - lowbit(i);
    }
    return s;
}
void B_search(int b,int k)
{
     int tem = sum(b);
    int low = b;
    int high = maxm;
    int mid;
    while(low <= high)
    {
        mid = (low + high) /2;
        int st = sum(mid);
        if(hash[mid]>0 && st-hash[mid]-tem<k&&st-tem>=k)//减hash是因为可能存在多个相同元素的情况
        {
            break;
        }
        if(st-tem<k)
        {
            low = mid + 1;
        }
        else
            high = mid - 1;
    }
    printf("%d\n",mid);
}
bool query(int b,int k)
{
    if(sum(maxn)-sum(b)<k)return 0;
    B_search(b,k);
    return 1;
}

int main()
{
    int n,a,b,k;
    while(scanf("%d",&n)!=EOF)
    {
        init(c);
        init(hash);

        for(int i=0;i<n;i++)
        {
            scanf("%d",&a);
            if(a==0)
            {
                scanf("%d",&b);
                add(b,1);
                hash[b]++;
            }
            else if(a==1)
            {
                scanf("%d",&b);
                if(hash[b]>0)
                {
                     add(b,-1);
                     hash[b]--;
                }
                else
                    puts("No Elment!");
            }
            else if(a==2)
            {
                scanf("%d%d",&b,&k);
               bool tep =  query(b,k);
               if(!tep)
                puts("Not Find!");
            }
        }
    }
    return 0;
}

HDU 2852 KiKi's K-Number(树状数组+二分)

时间: 2024-10-18 02:03:52

HDU 2852 KiKi's K-Number(树状数组+二分)的相关文章

HDU 2852 KiKi&#39;s K-Number【 树状数组 二分 】

题意:给出m个操作,0:是增加一个数,add(x,1)1:是删除一个指定的数,这个是看sum(x) - sum(x-1)是否为0,为0的话则不存在,不为0的话,则add(x,-1)2:是查询比x大的数中第k大的数,先求出比x小的个数s,假设比x大的数中第k大的数为y,那么比y小的个数有s+k个二分y的值来找 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath&g

HDU 2852 KiKi&#39;s K-Number (树状数组 &amp;&amp; 二分)

题意:给出对容器的总操作次数n, 接下来是这n个操作.这里对于一个容器提供三种操作, 分别是插入.删除和查找.输入0  e表示插入e.输入1  e表示删除e,若元素不存在输出No Elment!.输入2  e  k表示查找比e大且第k大的数, 若不存在则输出Not Find! 分析:这里考虑树状数组做的原因是在第三个操作的时候, 只要我们记录了元素的总数, 那通过求和操作, 便能够高效地知道到底有多少个数比现在求和的这个数要大, 例如 tot - sum(3)就能知道整个集合里面比3大的数到底有

hdu 2852 KiKi&#39;s K-Number (线段树)

hdu 2852 题意: 一个容器,三种操作: (1) 加入一个数 e (2) 删除一个数 e,如果不存在则输出 No Elment! (3) 查询比a大的数中的第k小数,不存在就输出 Not Find! 解法: 关于第三点,可以先查询小于等于a的数的个数cnt,然后直接查询第cnt+k小数就行了 . 二分+树状数组 或者 主席树(有点杀鸡用牛刀的感觉 ...) 也是可以做的  _(:з」∠)_ code:线段树 1 #include <iostream> 2 #include <cst

HDU 1394 Minimum Inversion Number 树状数组&amp;&amp;线段树

题目给了你一串序列,然后每次 把最后一个数提到最前面来,直到原来的第一个数到了最后一个,每次操作都会产生一个新的序列,这个序列具有一个逆序数的值,问最小的你逆序数的值为多少 逆序数么 最好想到的是树状数组,敲了一把很快,注意把握把最后一个数提上来对逆序数的影响即可, #include<iostream> #include<cstdio> #include<list> #include<algorithm> #include<cstring> #i

hdu-2852 KiKi&#39;s K-Number---二分+树状数组

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2852 题目大意: 题意:    给出三种操作,    0 在容器中插入一个数.    1 在容器中删除一个数.    2 求出容器中大于a的第k大元素. 解题思路: 用树状数组维护每个值,插入数字是add(x, 1),删除时add(x, -1) 查询第k大时,先判断是否存在,存在的话直接根据树状数组sum值的单调性二分法求解即可 1 #include<iostream> 2 #include&l

hdu 1541/poj 2352:Stars(树状数组,经典题)

Stars Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4052    Accepted Submission(s): 1592 Problem Description Astronomers often examine star maps where stars are represented by points on a plan

hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)

Increasing Speed Limits Time Limit: 2000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 481    Accepted Submission(s): 245 Problem Description You were driving along a highway when you got caught by the road p

hdu 5869 区间不同GCD个数(树状数组)

Different GCD Subarray Query Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 221    Accepted Submission(s): 58 Problem Description This is a simple problem. The teacher gives Bob a list of probl

hdu 1166:敌兵布阵(树状数组,练习题)

敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 37773    Accepted Submission(s): 15923 Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就