黑匣子-对顶堆

https://www.luogu.com.cn/problem/P1801#submit

#include <cstdio>
#include <queue>
#define Qmax priority_queue<int>
#define Qmin priority_queue<int,vector<int>,greater<int> >
#define f(i , a , b) for(int i=(a) ; i <= (b) ; i++)
using namespace std;
inline int Input(){
    char C=getchar();
    int N=0 , F=1;
    while(('0' > C || C > '9') && (C != '-')) C=getchar();
    if(C == '-') F=-1 , C=getchar();
    while('0' <= C && C <= '9') N=(N << 1)+(N << 3)+(C - 48) , C=getchar();
    return F*N; 
} 
int main(){
    int a[200001];
    Qmax A;
    Qmin B;
    int n=Input() , m=Input() , r=1 , q;
    f(i , 1 , n) a[i]=Input();
    f(i , 1 , m){
        q=Input();
        f(j , r , q){
            A.push(a[j]);
            if(A.size() == i) B.push(A.top()) , A.pop(); 
        }
        r=q+1;
        printf("%d\n" , B.top()); 
        A.push(B.top()) , B.pop(); 
    }
    return 0;
}

这道题的关键是使用对顶堆,小根堆维护前k大的数,大根堆维护前k小的数字,我们利用双指针算法每次更新时我们都利用大根堆的排序性质将每一个第i名都放进小根堆B之中,这样从小根堆中抽出的一定就是第i大的数字了

posted @ 2026-03-02 23:00  曾翎一  阅读(3)  评论(0)    收藏  举报