线段树HDU 2852

来源:互联网 发布:吸入麻醉药mac值表 编辑:程序博客网 时间:2024/06/03 14:17

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2852

代码风格:www.notonlysuccess.com


题目大意:操作说明0:加入一个数字a;1:删除一个数字a,如果不纯在a输出no elment; 2:输出比a大并且第k小的数字;如果不存在,输出 not find!

算法:线段树

思路:建一颗[1, 100000]的线段树,例如,把5加入第5个根节点……;删数的时候,如果该根节点没有值,就输出no elment,否则update; 求第k小的数时,先判断一共比它大的有几个数字,然后求比a大的第m大的数

#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;#define lson l, m, rt << 1#define rson m+1, r, rt << 1 | 1#define mid int m = (l+r) >> 1int cnt[898989];void update(int k, int c, int l, int r, int rt){    if(l == r)    {        if(cnt[rt] || c == 1)            cnt[rt] += c;        return ;    }    mid ;    if(k <= m)        update(k, c, lson);    else        update(k, c, rson);    cnt[rt] = cnt[rt << 1] + cnt[rt << 1 | 1];}int query(int k, int l, int r, int rt){    if(l == r)        return cnt[rt];    mid ;    if(k <= m)        return query(k, lson);    else        return query(k, rson);}int Query(int k, int l, int r, int rt){    if(l == r)        return 0;    mid ;    if(k <= m)        return Query(k, lson) + cnt[rt << 1 | 1];    else        return Query(k, rson);}int query1( int k, int l, int r, int rt){    if(l == r)    {        return l;    }    mid ;    if(cnt[rt << 1 | 1] < k)        return query1(k-cnt[rt << 1 | 1 ], lson);    else return query1(k, rson);}int main(){    int a, b;    int n;    int op;    while(scanf("%d", &n) != EOF)    {        memset(cnt, 0, sizeof(cnt));        while(n --)        {            scanf("%d", &op);            if(op == 0)            {                scanf("%d", &a);                update(a, 1, 1, 100000, 1);            }            else if(op == 1)            {                scanf("%d", &a);                int k = query(a, 1, 100000, 1);  //询问a点是否有数字                if(k == 0)                    printf("No Elment!\n");                else                {                    update(a, -1, 1, 100000, 1);     //把a点的数字删除                }            }            else            {                scanf("%d%d", &a, &b);                int k = Query(a, 1, 100000, 1);         //询问比a大的有几个数字                if(b <= k)                {                    printf("%d\n", query1(k-b+1, 1, 100000, 1));//找到并且输出第b大的数字                }                else                {                    printf("Not Find!\n");                }            }        }    }return 0;}


原创粉丝点击