题目限定数的范围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; }