• hdu-2852 KiKi'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<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<map>
     6 #include<set>
     7 #include<cmath>
     8 #include<algorithm>
     9 #include<vector>
    10 #include<sstream>
    11 #define lowbot(i) (i&(-i))
    12 using namespace std;
    13 typedef long long ll;
    14 const int maxn = 1e5 + 10;
    15 int tree[maxn];
    16 void add(int x, int d)
    17 {
    18     while(x <= 100000)
    19         tree[x] += d, x += lowbot(x);
    20 }
    21 int sum(int x)
    22 {
    23     int ans = 0;
    24     while(x)ans += tree[x], x -= lowbot(x);
    25     return ans;
    26 }
    27 int Find(int x, int k)
    28 {
    29     int l = x + 1, r = 100000;
    30     int mid, t;
    31     while(l < r)
    32     {
    33         //cout<<l<<" "<<r<<endl;
    34         mid = (l + r) / 2;
    35         t = sum(mid) - sum(x);
    36         if(t >= k)
    37             r = mid;
    38         else l = mid + 1;
    39     }
    40     return r;
    41 }
    42 int main()
    43 {
    44     int n, x, k;
    45     while(scanf("%d", &n) != EOF)
    46     {
    47         memset(tree, 0, sizeof(tree));
    48         while(n--)
    49         {
    50             scanf("%d", &x);
    51             if(x == 0)
    52             {
    53                 scanf("%d", &x);
    54                 add(x, 1);
    55             }
    56             else if(x == 1)
    57             {
    58                 scanf("%d", &x);
    59                 if(sum(x) == sum(x - 1))
    60                     printf("No Elment!
    ");
    61                 else add(x, -1);
    62             }
    63             else if(x == 2)
    64             {
    65                 scanf("%d%d", &x, &k);
    66                 if(sum(100000) - sum(x) < k)
    67                     printf("Not Find!
    ");
    68                 else
    69                 {
    70                     printf("%d
    ", Find(x, k));
    71                 }
    72             }
    73         }
    74     }
    75     return 0;
    76 }
  • 相关阅读:
    20165312 我期望的师生关系
    zookeeper04---ZAB协议
    zookeeper03-集群搭建
    zookeeper02
    Zookeeper01
    防止重复提交
    手动抛出异常事务回滚问题
    redis-07主从复制
    redis06-事务
    Redis-05持久化
  • 原文地址:https://www.cnblogs.com/fzl194/p/8955062.html
Copyright © 2020-2023  润新知