$Poj3784 Running Median$

Posted forward777

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了$Poj3784 Running Median$相关的知识,希望对你有一定的参考价值。

Poj

 

Description

 动态维护中位数问题

 

Sol

 "对顶堆"的在线做法

建立两个二叉堆,一个大根堆一个小根堆

在依次读入这个整数序列的过程中,设当前序列为l,要始终保证:

1.序列中从小到大排名为1~l/2的整数存在大根堆中

2.序列中从小到大排名为l/2+1~l的整数存在小根堆中

每次插入一个数,与之前的中位数相比较,如果较小就插入大根堆,反之..

必须要维护两个堆中的元素数目相差最多为1,否则取出数目多的堆顶加入另一个堆

小根堆的堆顶即为中位数

最后还有来自gql的两点注意qwq:

技术图片

 

Code

技术图片
#include<iostream>
#include<cstdio>
#include<queue>
#define il inline
#define Rg register
#define go(i,a,b) for(Rg int i=a;i<=b;i++)
#define yes(i,a,b) for(Rg int i=a;i>=b;i++)
using namespace std;
il int read()

    int x=0,y=1;char c=getchar();
    while(c<0||c>9)if(c==-)y=-1;c=getchar();
    while(c>=0&&c<=9)x=(x<<1)+(x<<3)+c-0;c=getchar();
    return x*y;

int t,t1,n,nw;
priority_queue<int>q1;
priority_queue<int,vector<int>,greater<int> >q2;
int main()

    t=read();
    while(t--)
    
        t1=read(),n=read();printf("%d %d\\n",t1,n/2+1);
        while(q1.size()>0)q1.pop();
        while(q2.size()>0)q2.pop();
        go(i,1,n)
        
            int x=read();
            if(i==1)nw=x;q2.push(x);
            else
            
                if(x<nw)q1.push(x);
                else q2.push(x);
            
            while((int)q1.size()>(int)q2.size())int y=q1.top();q1.pop();q2.push(y);
            if((int)q2.size()-(int)q1.size()>1)int y=q2.top();q2.pop();q1.push(y);
            nw=q2.top();
            if(i&1)printf("%d ",nw);
            if((i&1)&&(i/2+1)%10==0)printf("\\n");
        
        if((n/2+1)%10)printf("\\n");
    
    return 0;
View Code

 

以上是关于$Poj3784 Running Median$的主要内容,如果未能解决你的问题,请参考以下文章

POJ3784Running Median

POJ 3784 Running Median

POJ 3784 Running Median

Running Median POJ - 3784 (对顶堆/优先队列)

POJ 3784 Running Median(动态维护中位数)

poj3784Running Median——堆维护中间值