【对顶堆】POJ 3784 Running Median

链接

http://poj.org/problem?id=3784

大意

输入 n 个数,要求第奇数次输入时,输出该序列的中位数

思路

对顶堆在线维护中位数

建立两个堆,大根堆和小根堆,令小根堆中元素的个数大于等于大根堆中元素的个数,其次,我们还需保证小根堆里的每个值必须大于等于大根堆的堆顶

代码

#include<algorithm>
#include<cstdio>
#include<queue>
#define r(i,a,b) for(register int i=a;i<=b;i++)
using namespace std;int t,i,n,x,j;
priority_queue<int,vector<int>,greater<int> >mi;
priority_queue<int,vector<int>,less<int> >mx;
inline int read()
{
    int f=0,d=1;char c;
    while(c=getchar(),c<48||c>57) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
    while(c=getchar(),c>47&&c<58) f=(f<<3)+(f<<1)+c-48;
    return d*f;
}
inline void write(register int x)
{
    if(x<0){x=-x;putchar('-');}
    if(x>9)write(x/10);
    putchar(x%10+48);
    return;
}
signed main()
{
    t=read();
    r(k,1,t)
    {
        while(mx.size())mx.pop();
        while(mi.size())mi.pop();
        i=read();n=read();
        write(k);putchar(32);write((n+1)>>1);putchar(10);
        x=read();
        write(x);
        mx.push(x);//先放入一个元素
        for(i=2,j=1;i<=n;i++)
        {
            x=read();
            if(mx.top()>=x) mx.push(x);else mi.push(x);//维护
            if(i&1)
            {
                if(j==10) putchar(10),j=0;else putchar(32);
                write(mx.size()>mi.size()?mx.top():mi.top());//输出
                j++;
            }
            else
            {
                if(mx.size()>mi.size()) //维护
                {
                    mi.push(mx.top());
                    mx.pop();
                }
                if(mx.size()<mi.size()) 
                {
                    mx.push(mi.top());
                    mi.pop();
                }
            }
        }
        putchar(10);
    }
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/81738863
今日推荐