维护有删除操作的动态区间中位数
一般常用的维护区间中位数的方法是用大顶堆
与小顶堆
来操作
但是如果涉及到删除
操作那么用这种方法便不是很好操作(也许是我太菜
)
构造开始
我们维护删除操作的方法就是用set
模拟大小顶堆
那么既然用的set
,那么我们的区间里的每个数都必须是不同的 , 我大概想了下 , 如果要有相同值的话 , 我们就要用map
了 ,这里我直接贴set
的代码了,有空再更新map
的代码,对了,用map
来维护的话,我们记得要erase
掉map
的value==0
的key
这样才能保证我们的取begin值是最大或者最小的
struct app{
int val;
}temd;
bool operator<(app tema,app temb){
return tema.val<temb.val;//小顶堆存大于中位数的值
}
struct bpp{
int val;
}temx;
bool operator<(bpp tema,bpp temb){
return tema.val>temb.val;//大顶堆存小于中位数的值
}
set<app> da;//储存大于中位数的值
set<bpp> xiao;//存储小于中位数的值
int zhong=-1;//储存中位数
void charu( int item ){
if(zhong==-1){
zhong=item;return;
}
if( item>zhong ){
temd.val=item;
da.insert(temd);
}else{
temx.val=item;
xiao.insert(temx);
}
if( da.size()>xiao.size() ){
temx.val=zhong;
xiao.insert( temx );
zhong= da.begin()->val ;
temd.val=zhong;
da.erase( temd );
return;
}
if( da.size() + 1 <xiao.size() ){
temd.val=zhong;
da.insert( temd );
zhong=xiao.begin()->val;
temx.val=zhong;
xiao.erase( temx );
return;
}
}
void sanchu(int item){
if( item==zhong ){
if( da.size()==xiao.size() && da.size()!=0 ){
zhong= da.begin()->val;
temd.val=zhong;
da.erase( temd );
}else if( xiao.size()!=0 ){
zhong = xiao.begin()->val;
temx.val=zhong;
xiao.erase( temx );
}else{
zhong=-1;
}
return;
}
if(item>zhong){
temd.val=item;
da.erase( temd );
if( (int)(da.size() + 1) < (int)xiao.size() ){
temd.val=zhong;
da.insert( temd );
zhong= xiao.begin()->val;
temx.val=zhong;
xiao.erase( temx );
return;
}
}else{
temx.val=item;
xiao.erase( temx );
if( da.size() > xiao.size() ){
temx.val=zhong;
xiao.insert( temx );
zhong= da.begin()->val;
temd.val=zhong;
da.erase( temd );
return;
}
}
}