poj 3784 Running Median 二叉堆

来源:互联网 发布:百度大数据官网 编辑:程序博客网 时间:2024/05/22 05:20

传送门


题目大意:
依次添加 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

0 0
原创粉丝点击