分块思想解法
#include <cmath>
#include <cstdio>
#include <cstring>
#include <stack>
using namespace std;
const int maxn = 100010;
const int sqrN = 316;
stack<int> st;
int block[sqrN];
int table[maxn];
void peekMedian(int K) {
int sum = 0;
int idx = 0;
while (sum + block[idx] < K) {
sum += block[idx++];
}
int num = idx * sqrN;
while (sum + table[num] < K) {
sum += table[num++];
}
printf("%d\n", num);
}
void Push(int x) {
st.push(x);
block[x / sqrN]++;
table[x]++;
}
void Pop() {
int x = st.top();
st.pop();
block[x / sqrN]--;
table[x]--;
printf("%d\n", x);
}
int main() {
int x, query;
memset(block,0,sizeof(block));
memset(table, 0, sizeof(table));
char cmd[20];
scanf("%d",&query);
for(int i=0;i<query;i++){
scanf("%s",cmd);
if(strcmp(cmd,"Push")==0){
scanf("%d",&x);
Push(x);
}else if(strcmp(cmd,"Pop")==0){
if(st.empty()==true){
printf("Invalid\n");
}else{
Pop();
}
}else{
if(st.empty()==true){
printf("Invaild\n");
}else {
int K=st.size();
if(K%2==1)K=(K+1)/2;
else K=K/2;
peekMedian(K);
}
}
}
return 0;
}
树状数组解法
#include <cmath>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define lowbit(i) ((i)&-(i))
const int MAXN=100010;
stack<int>s;
int c[MAXN];
void update(int x,int v){
for(int i=x;i<MAXN;i+=lowbit(i)){
c[i]+=v;
}
}
int getSum(int x){
int sum=0;
for(int i=x;i>0;i-=lowbit(i)){
sum+=c[i];
}
return sum;
}
void PeekMedian(){
int l=1,r=MAXN,mid,K=(s.size()+1)/2;
while(l<r){
mid=(1+r)/2;
if(getSum(mid)>=K)r=mid;
else l=mid+1;
}
printf("%d\n",l);
}
int main(){
int n,x;
char str[12];
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%s",str);
if(strcmp(str,"Push")==0){
scanf("%d",&x);
s.push(x);
update(x,1);
}else if(strcmp(str,"Pop")==0){
if(s.empty()) printf("Invaild\n");
else
{
printf("%d\n",s.top());
update(s.top(),-1);
s.pop();
}
}else if(strcmp(str,"PeekMedian")==0){
if(s.empty())printf("Invaild\n");
else PeekMedian();
}
}
return 0;
}