利用树状数组来做,树状节点储存该区间内的数字个数
树状数组每个节点x负责的区间为[x - 2^k + 1,x]
其中k为x用二进制表示中末尾0的个数
#include<stdio.h>
#include<stack>
#include<algorithm>
#include<string.h>
using namespace std;
#define SIZE 100001
struct key{
int num;
int flag;
};
class TreeArr{
private:
int a[SIZE];
int lowbit(int x){
return x&(-x);
}
public:
TreeArr(){
memset(a, 0, sizeof(a));
}
void update(int num, int value){
while (num <= SIZE){
a[num] += value;
num += lowbit(num);
}
}
int sum(int pos){
int value(0);
while (pos>0){
value += a[pos];
pos -= lowbit(pos);
}
return value;
}
int find(int num, int begin = 0, int end = SIZE){
if (begin == end)
return begin;
int mid = (begin + end) / 2;
if (sum(mid) >= num){
return find(num, begin, mid);
}
else return find(num, mid+1, end);
}
};
int main(){
stack<int>s;
TreeArr tree;
freopen("1.in", "r", stdin);
int n;
scanf("%d", &n);
while (n--){
char cmd[20];
scanf("%s", cmd);
if (strcmp(cmd, "Pop") == 0){
if (!s.size())
printf("Invalid\n");
else{
printf("%d\n", s.top());
tree.update(s.top(), -1);
s.pop();
}
}
else if (!strcmp(cmd, "Push")){
int key;
scanf("%d", &key);
s.push(key);
tree.update(key, 1);
}
else if (!strcmp(cmd, "PeekMedian")){
if (!s.size())
printf("Invalid\n");
else{
printf("%d\n", tree.find((s.size()+1) / 2));
}
}
}
return 0;
}