题目限定数的范围N<=100000
关键点:构建树状数组可以求解前n个数的和
由此push和pop时要维护树状数组,当需要求解median时,使用二分法
由此总的算法复杂度为O(N*logN+N*logn*logN)=O(N*logN*logN)
// 1057. Stack (30).cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
const int N = 100003;
int ind[N];
int data[N];
int vol[N];
int ssize;
int lowbit(int x){
return x & (-x);
}
void update(int pos, int inc){
while(pos <= N){
ind[pos] += inc;
pos += lowbit(pos);
}
}
int sum(int pos){
int ret = 0;
while(pos > 0){
ret += ind[pos];
pos -= lowbit(pos);
}
return ret;
}
//binarySearch the minimum value x that sum(x) = keyValue(the ascend sorting index of median)
int binarySearch(int low, int high, int keyValue){
while(low <= high){
int mid = (low + high) / 2;
int tmpSum = sum(mid);
if(keyValue <= tmpSum)
high = mid - 1;
else
low = mid + 1;
}
return low;
}
int main(){
int cas;
scanf("%d", &cas);
memset(ind, 0, sizeof(ind));
memset(vol, 0, sizeof(vol));
char cmd[13];
ssize = 0;
while(cas--){
scanf("%s", cmd);
if(cmd[1] == 'u'){
int tmp;
scanf("%d", &tmp);
data[ssize] = tmp;
vol[tmp]++;
update(tmp, 1);
ssize++;
}
else if(cmd[1] == 'o'){
if(ssize == 0)
printf("Invalid\n");
else{
update(data[--ssize], -1);
printf("%d\n", data[ssize]);
}
}
else{
if(ssize == 0)
printf("Invalid\n");
else{
int keyValue = (ssize & 0x01) ? (ssize + 1) / 2 : (ssize / 2);
int ans = binarySearch(1, N, keyValue);
printf("%d\n", ans);
}
}
}
return 0;
}