题目:
hdu2852
题意:
有一个盒子,有如下操作:
0 x:往盒子里放一个数 x,( x 可以多次放入)
1 x:从盒子里删掉一个数 x。(如果 x 有多个,只删1个,如果没有,则输出No Elment!)
2 x k:查询盒子里大于 x 的第 K 个数。(如果没有,则输出Not Find!)
思路:
树状数组 + 二分查找
代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#define lowbit(a) ((a) & (-a))
using namespace std;
const int MAXN = 1e5 + 10;
int tree[MAXN];
int final, maxe;
void add(int x, int d){
while (x <= final){
tree[x] += d;
x = x + lowbit(x);
}
}
int sum(int x){
int cnt = 0;
while (x > 0){
cnt += tree[x];
x -= lowbit(x);
}
return cnt;
}
void find (int l, int k){
int s = sum(l), r = maxe;
if (sum(r) - s < k){
printf("Not Find!\n");
return;
}
int mid;
while (l <= r){
mid = (l + r) >> 1;
if (sum(mid) - s >= k)
r = mid - 1;
else
l = mid + 1;
}
printf("%d\n", r + 1);
}
int main(){
// freopen("_in.txt", "r", stdin);
// freopen("_out1.txt", "w", stdout);
int n;
int op, a, b;
final = MAXN - 5;
while (~scanf("%d", &n)){
memset(tree, 0, sizeof(tree));
maxe = 0;
while (n--){
scanf("%d", &op);
if (op == 0){
scanf("%d", &a);
add(a, 1);
maxe = max(maxe, a);
}
else if (op == 1){
scanf("%d", &a);
if (sum(a) - sum(a-1) == 0)
printf("No Elment!\n");
else
add(a, -1);
}
else{
scanf("%d%d", &a, &b);
find(a, b);
}
}
}
return 0;
}