洛谷P1168 中位数 堆

Posted third2333

tags:

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

洛谷P1168 中位数   堆 
求a[ 1 ] --a[ 1 ] 的中位数 ,a[ 1 ]--a[ 3 ] 的中位数 a[ 1 ]--a[ 5 ] 的中位数

题解
1、假设我们已知 a[ 1 ]--a[ i ] 的中位数 (i&1) 此时我们求 a[ 1 ]--a[ i+2 ] 的中位数
那么我们可以把比他大的划到一份中,比他小的划到一份中,如果两份数的个数相同,则其仍然是
中位数
2、如果不同,比如说 big > small 那我们就把比他大的数 作为中位数 ans 到比中位数小的数中
因为原本size相差2 现在size 相同了,所以此时的ans就是答案

因为我们动态提取最大和最小,那我们就可以求 比他大的数 用小根堆维护,
比他 小的数用大根堆维护

 

 

#include <cstdio>
#include <vector>
#include <queue> 
using namespace std ; 

const int maxn = 100011 ; 
int n,ans,size ; 
int a[maxn] ; 
priority_queue <int,vector<int>,greater<int> > big ;   //  小根堆
priority_queue <int,vector<int>,less<int> >small ;   //  大根堆 
 

int main() 
{
    scanf("%d",&n) ;
    for(int i=1;i<=n;i++ ) scanf("%d",&a[ i ]) ; 
    ans = a[1] ;
    printf("%d\n",ans) ; 
    for(int i=2;i<=n;i+=2) 
    {
        if(i+1>n) break ; 
        for(int j=i;j<=i+1;j++) 
            if(a[j]>ans) big.push(a[ j ]) ;
                else     small.push(a[ j ]) ;
        size = (i+1)/2 ; 
        if(big.size()>size) small.push(ans),ans = big.top(),big.pop() ;
        if(small.size()>size) big.push(ans),ans = small.top(),small.pop() ;
        printf("%d\n",ans) ; 
    }
    return 0 ; 
}

 

以上是关于洛谷P1168 中位数 堆的主要内容,如果未能解决你的问题,请参考以下文章

[洛谷P1168]中位数

洛谷—— P1168 中位数

洛谷 P1168 中位数

洛谷P1168中位数(Splay)/(主席树)

[luogu]P1168 中位数[堆]

P1168 中位数[堆 优先队列]