$Poj3784 Running Median$
Posted forward777
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了$Poj3784 Running Median$相关的知识,希望对你有一定的参考价值。
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;
以上是关于$Poj3784 Running Median$的主要内容,如果未能解决你的问题,请参考以下文章
Running Median POJ - 3784 (对顶堆/优先队列)