《算法竞赛进阶指南》0x05排序 POJ3784 对顶堆动态维护中位数

题目链接:http://poj.org/problem?id=3784

对顶堆算法:输入M个数的时候,将其中1~[M/2]个小的数存入大顶堆,将剩余数存入小顶堆,如果大顶堆中的数的数量大于[M/2]就讲堆顶元素取出扔到小顶堆中去,

当扫描到计数数量时,输出小顶堆的堆顶元素,也就是第[M/2]+1大的元素,这个元素就是整个序列的中位数,时间复杂度约为O(nlogn)。

代码如下:

#include<iostream>
#include<queue>
using namespace std;
typedef unsigned int ui;
typedef long long ll;
typedef unsigned long long ull;
#define pf printf
#define mem(a,b) memset(a,b,sizeof(a))
#define prime1 1e9+7
#define prime2 1e9+9
#define pi 3.14159265
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define scand(x) scanf("%llf",&x) 
#define f(i,a,b) for(int i=a;i<=b;i++)
#define scan(a) scanf("%d",&a)
#define mp(a,b) make_pair((a),(b))
#define P pair<int,int>
#define dbg(args) cout<<#args<<":"<<args<<endl;
#define inf 0x7ffffff
inline int read(){
    int ans=0,w=1;
    char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
    while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
    return ans*w;
}
int n,m,t;
const int maxn=1e5+10;
const ll mod=10000;
priority_queue<int,vector<int>,less<int> >q1;// 大根堆
priority_queue<int,vector<int>,greater<int> >q2;//小根堆
int main()
{
   // freopen("input.txt","r",stdin);
   // freopen("output.txt","w",stdout);
   t=read();
   int num;
   while(t--){
           while(q1.size())q1.pop();
        while(q2.size())q2.pop();
        cin>>num>>n;
        cout<<num<<" "<<(n+1)/2<<endl;
        int a;
        cin>>a;
        cout<<a<<" ";//1为奇数,输出第一个元素 
        q2.push(a);//中位数在小根堆中 
        int cnt=1;
        f(i,2,n){
            scanf("%d",&a);
            if(a<q2.top())q1.push(a);
            else q2.push(a);
            int s=q1.size();
            if(s>i/2){//大顶堆中的元素过多,调整到小顶堆中去 
                q2.push(q1.top());
                q1.pop();
            }
            if(s<i/2){
                q1.push(q2.top());
                q2.pop();
            }
            if(i%2){//输出奇数时刻的中位数 
                cout<<q2.top()<<" ";
                if(++cnt%10 == 0)cout<<endl;//每行十个数 
            }
        }
        if(cnt%10 != 0)
        cout<<endl; 
   }
}

 

posted @ 2020-06-15 16:40  WA自动机~  阅读(148)  评论(0编辑  收藏  举报