hdu-2852 KiKi's K-Number---二分+树状数组

Posted 努力努力再努力x

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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!\n");
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!\n");
68                 else
69                 {
70                     printf("%d\n", Find(x, k));
71                 }
72             }
73         }
74     }
75     return 0;
76 }

 





以上是关于hdu-2852 KiKi's K-Number---二分+树状数组的主要内容,如果未能解决你的问题,请参考以下文章

HDU2852 KiKi's K-Number

hdu 2852 KiKi's K-Number (线段树)

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

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

*HDU2852 树状数组(求第K小的数)

kiki's game