hdu2852(线段树求第k大数)

来源:互联网 发布:大数据金融行业运用 编辑:程序博客网 时间:2024/06/16 18:21

题目链接:hdu2852

/*hdu2852 线段树求第k大数题意:有三种操作,1、0 x 向容器中插入一个数x                  2、1 x 在容器中删除一个数x                  3、2 x k,求出容器中大于x的第k个元素。思路:求出容器中大于x的第k个元素,可以先求出<=a的元素的数量cnt,然后就等价于求区间[1..N]中第Kth = cnt+k的元素…注意:相同的数可以插入多个*/#include <iostream>#include <queue>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <cstdlib>#include <string>#include <map>using namespace std;const int N = 100010;#define lson rt<<1#define rson rt<<1|1struct node{    int l,r,sum;}s[N<<2];int v[N];//标记已经插入的数void build(int l, int r, int rt){    s[rt].l = l;  s[rt].r = r;    s[rt].sum = 0;    if(l == r) return;    int mid = (l+r) >> 1;    build(l, mid, lson);    build(mid+1, r, rson);}void update(int pos, int num, int rt){    if(s[rt].l == pos && pos == s[rt].r){        s[rt].sum += num;        return;    }    int mid = (s[rt].l + s[rt].r) >> 1;    if(pos <= mid)        update(pos, num, lson);    if(mid < pos)        update(pos, num, rson);    s[rt].sum = s[lson].sum + s[rson].sum;}int query(int num, int l, int r, int rt){    if(s[rt].l == s[rt].r) return s[rt].l;    int mid = (s[rt].l + s[rt].r) >> 1;    if(num <= s[lson].sum)        return query(num, l, r, lson);    else        return query(num-s[lson].sum, l, r, rson);}int getsum(int l, int r, int rt){    if(l <= s[rt].l && s[rt].r <= r)        return s[rt].sum;    int mid = (s[rt].l + s[rt].r) >> 1;    int ans = 0;    if(l <= mid)        ans += getsum(l, r, lson);    if(mid < r)        ans += getsum(l, r, rson);    return ans;}int main(){    int n,i,x,k,op;    while(~scanf("%d",&n))    {        build(1, N, 1);        memset(v, false, sizeof(v));        while(n --){            scanf("%d",&op);            if(op == 0){                scanf("%d",&x);                update(x, 1, 1);                v[x] ++;            }            if(op == 1){                scanf("%d",&x);                if(!v[x])                    puts("No Elment!");                else{                    update(x, -1, 1);                    v[x] --;                }            }            if(op == 2){                scanf("%d%d",&x,&k);                int cnt = getsum(1, x, 1);//查找<=x的数的个数                if(s[1].sum < cnt + k)                    puts("Not Find!");                else{                    int ans = query(cnt+k, 1, N, 1);                    printf("%d\n",ans);                }            }        }    }    return 0;}


0 0