入栈和出栈操作就用stack就好,难点是求中值,作者用到的是树状数组,树状数组中的每个元素的值t[k]代表k出现的次数,对push操作,使t[k]+1;对pop操作,使t[k]-1;对求中值操作,二分查找前缀和,求第一个前缀和sum[k]>=(st.size()+1)/2的值,这个值k就是中值(中位数)。
#include <iostream>
#include <stack>
#define N 100010
using namespace std;
stack<int> st;
int n,x,t[N];
char s[100];
void add(int x,int c){//更新
for(;x<=1e5;x+=x&-x) t[x]+=c;
}
int sum(int x){//前缀和t[1~n]
int ans=0;
for(;x;x-=x&-x) ans+=t[x];
return ans;
}
int main(){
scanf("%d",&n);
while(n--){
scanf("%s",s);
if(s[1]=='o'){
if(st.empty()) printf("Invalid\n");
else{
add(st.top(),-1);//更新树状数组
printf("%d\n",st.top());
st.pop();
}
}
else if(s[1]=='e'){
if(st.empty()) printf("Invalid\n");
else{
int l=1,r=1e5,mid,ans;
while(l<=r){//二分查找中值
mid=(l+r)/2;
ans=sum(mid);
if(ans<(st.size()+1)/2) l=mid+1;
else r=mid-1;
}
printf("%d\n",r+1);
}
}
else if(s[1]=='u'){
scanf("%d",&x);
st.push(x);
add(x,1);//更新树状数组
}
}
return 0;
}