显然中位数为排序后第(n+1)/2个数
define m (n+1)/2
考虑维护两个堆
一个大根堆(s1),里面为前m个元素;一个小根堆(s2),里面为后n-m个元素
修改和询问的流程如下
每次加入一个数x时
如果x<=s1.top
add x to s1
如果|s1|>|s2|+1
move s1.top to s2
else
add x to s2
如果|s2|>|s1|
move s2.top to s1
每次询问
输出s1.top
显然正确
#include<bits/stdc++.h>
#define fsb(a,b,c) for(int a=b;a<=c;a++)
#define fbs(a,b,c) for(int a=b;a>=c;a--)
using namespace std;
int n=0,m,x,sz1=0,sz2=0;
char s[10];
struct node1{
int x;
};
struct node2{
int x;
};
int operator<(node1 a,node1 b){
return a.x<b.x;
}
int operator<(node2 a,node2 b){
return a.x>b.x;
}
priority_queue<node1>s1;
priority_queue<node2>s2;
template<typename qw>inline void rll(qw &x){
qw f=1;x=0;char c=getchar();
while(!isdigit(c))f=c=='-'?-1:f,c=getchar();
while(isdigit(c))x=x*10+c-'0',c=getchar();
x*=f;
}
inline void add(int x){
if(s1.empty()){
s1.push((node1){x});sz1++;return;
}
if(x<=s1.top().x){
s1.push((node1){x});sz1++;
if(sz1>sz2+1){
int t=s1.top().x;s1.pop();
s2.push((node2){t});sz1--;sz2++;
}
}else{
s2.push((node2){x});sz2++;
if(sz2>sz1){
int t=s2.top().x;s2.pop();
s1.push((node1){t});sz1++;sz2--;
}
}
}
int main(){
rll(m);
fsb(i,1,m){
rll(x);add(x);
}
rll(m);
fsb(i,1,m){
scanf("%s",s+1);
if(s[1]=='a'){
rll(x);add(x);
}else{
printf("%d\n",s1.top().x);
}
}
return 0;
}