POJ 3784 Running Median 对顶堆算法

来源:互联网 发布:amos软件 编辑:程序博客网 时间:2024/05/16 15:51

题意:一组数按顺序加入数组,每奇数次加入的时候就输出中位数

如果是求最大最小值,那么我们很容易就会想到利用堆

那么这道题很明显也可以用堆的办法解决——

对顶堆是一种可以O(LOGN)维护在线第K小值的算法

思想是维护两个堆,一个小根堆,一个大根堆,保证大根堆中的任意元素小于小根堆,并维护两堆元素数平衡

其中一堆堆顶即为中位数

#include<stdio.h>#include<string.h>#include<stdlib.h>void swap(int &x,int &y){int z=x;x=y;y=z;}struct small_root_heap{//小根堆    int heap[5010],top;    void insert(int x)//插入    {        heap[++top]=x;        int t=top;        while(t>1&&heap[t]<heap[t>>1])        swap(heap[t],heap[t>>1]),t>>=1;    }    void pop()//弹顶    {        int t=2;        heap[1]=heap[top];heap[top--]=0;        while(t<=top)           {                      if(heap[t]>heap[t+1]&&t<top)t++;            if(heap[t]<heap[t>>1])swap(heap[t],heap[t>>1]),t<<=1;            else break;        }    }}topheap,bottomheap,empty;//两个堆,其中上堆是小根堆,下堆是大根堆 void add(int x)//插入{    if(x<=-bottomheap.heap[1])bottomheap.insert(-x);    else topheap.insert(x);    //插入,保证下堆的任意元素都小于等于上堆的任意元素     //注意一定要和下堆堆顶比较,因为第一次插入后元素一定在下堆,如果和上堆堆顶比较就会WA    while(topheap.top>bottomheap.top)bottomheap.insert(-topheap.heap[1]),topheap.pop();    while(bottomheap.top>topheap.top+1)topheap.insert(-bottomheap.heap[1]),bottomheap.pop();    //维护上下堆平衡,保证两堆元素数相等或下堆元素数比上堆元素数多1 }int main(){    int p,i,j,k,x,m;    scanf("%d",&p);    for(j=1;j<=p;j++)    {        scanf("%d%d",&i,&m);        topheap=bottomheap=empty;        printf("%d %d\n",i,m+1>>1);        for(k=1;k<=m;k++)        {            scanf("%d",&x);add(x);            if(k&1){                printf("%d%c",-bottomheap.heap[1],k==m?'\n':' ');                if(k%20==19)printf("\n");            }        }    }}


0 0
原创粉丝点击