题意:
最开始有一个空的数组,有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 ",r); 77 } 78 } 79 } 80 } 81 return 0; 82 }