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

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

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

POJ 3784 Running Median 对顶堆算法_小根堆


对顶堆是一种可以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");
            }
        }
    }
}