您的位置:首页 > 其它

poj 3784 Running Median 二叉堆

2016-07-06 21:11 316 查看
传送门

题目大意:

依次添加 n 个数,要求第奇数次添加时,输出当前数列中的中位数。

分析:

维护一个大根堆一个小根堆,大的数插入小根堆,小的数插入大根堆,每次取大根堆堆顶就是中位数

代码如下:(第一次手写二叉堆,所以是抄的POPOQQQ的模板>o< >_<)

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=5000+5;
int p,a,m;
struct small_root_heap{//小根堆
int heap[maxn],size;
void insert(int x){
heap[++size]=x;
int t=size;
while(t>1&&heap[t]<heap[t>>1])//不断向上调整直到比父结点不优为止
swap(heap[t],heap[t>>1]),t>>=1;
}
void pop(){//弹顶
int t=2;
heap[1]=heap[size],heap[size--]=0;
while(t<=size){
if(heap[t]>heap[t+1]&&t<size)
t++;
if(heap[t]<heap[t>>1])//不断向上调整直到比父结点不优为止
swap(heap[t],heap[t>>1]),t<<=1;
else
break;
}
}
}topheap,bottomheap,empty;//topheap是小根堆,bottomheap是大根堆
void add(int x){
if(x<=-bottomheap.heap[1])
bottomheap.insert(-x);
else
topheap.insert(x);//小的插入大根堆,大的插入小根堆
//插入,保证下堆的任意元素都小于等于上堆的任意元素
//注意一定要和下堆堆顶比较,因为第一次插入后元素一定在下堆,如果和上堆堆顶比较就会WA
while(topheap.size>bottomheap.size)
bottomheap.insert(-topheap.heap[1]),topheap.pop();
while(bottomheap.size>topheap.size+1)
topheap.insert(-bottomheap.heap[1]),bottomheap.pop();
//维护上下堆平衡,保证两堆元素数相等或下堆元素数比上堆元素数多1
}
signed main(void){
scanf("%d",&p);
while(p--){
scanf("%d%d",&a,&m);
topheap=bottomheap=empty;
printf("%d %d\n",a,(m+1)>>1);
for(int i=1,x;i<=m;i++){
scanf("%d",&x);
add(x);
if(i&1){
printf("%d%c",-bottomheap.heap[1],i==m?'\n':' ');
if(i%20==19)
printf("\n");
}
}
}
return 0;
}


by >o< neighthorn
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: