hdu 2852 KiKi's K-Number

题意:

最开始有一个空的数组,有3中操作:

1.插入一个元素

2.删除一个元素

3.查询比a大的第k个元素是多少。

思路:

主要是第三个操作

树状数组求第k大是用的二分,判断满足的条件是大于等于0

这题首先得求出小于等于a的元素,假设是cnt,那么大于它的第k个元素,求的就是整个数组的第cnt + k小元素,直接二分就行了。

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 using namespace std;
 5 const int N = 1e5 + 10;
 6 int c[N];
 7 int vis[N];
 8 int lowbit(int x)
 9 {
10     return x&(-x);
11 }
12 void add(int x,int y)
13 {
14     for (int i = x;i <= N - 5;i += lowbit(i)) c[i] += y;
15 }
16 int getsum(int x)
17 {
18     int ans = 0;
19     for (int i = x;i > 0;i -= lowbit(i)) ans += c[i];
20     return ans;
21 }
22 int main()
23 {
24     int m;
25     while (scanf("%d",&m) != EOF)
26     {
27         memset(c,0,sizeof(c));
28         memset(vis,0,sizeof(vis));
29         int cnt = 0;
30         while (m--)
31         {
32             int op;
33             scanf("%d",&op);
34             if (op == 0)
35             {
36                 int e;
37                 scanf("%d",&e);
38                 vis[e]++;
39                 add(e,1);
40                 cnt++;
41             }
42             if (op == 1)
43             {
44                 int e;
45                 scanf("%d",&e);
46                 if (vis[e] <= 0)
47                 {
48                     puts("No Elment!");
49                 }
50                 else
51                 {
52                     add(e,-1);
53                     vis[e]--;
54                     cnt--;
55                 }
56             }
57             if (op == 2)
58             {
59                 int a,k;
60                 scanf("%d%d",&a,&k);
61                 int tmp = getsum(a);
62                 if (tmp + k > cnt)
63                 {
64                     puts("Not Find!");
65                 }
66                 else
67                 {
68                     int l = 1,r = N;
69                     while (r - l > 1)
70                     {
71                         int mid = (l + r) >> 1;
72                         if (getsum(mid) >= tmp + k) r = mid;
73                         else l = mid + 1;
74                     }
75                     while (getsum(r-1) >= tmp + k) r--;
76                     printf("%d\n",r);
77                 }
78             }
79         }
80     }
81     return 0;
82 }

猜你喜欢

转载自www.cnblogs.com/kickit/p/9080883.html