「题解」洛谷 P1801 黑匣子

题目

P1801 黑匣子

简化题意

给你一堆数,每次让你求前多少个数中的第 (k) 小的数。

思路

大根堆 +小根堆。

没有询问前把数都加到大根堆里,有询问的时候当大根堆里的元素不少于 (k) 的时候就把堆顶的元素放到小跟堆里,最后小根堆堆顶的元素就是答案,最后要把小根堆堆顶的元素放回大根堆中。

Code

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#define MAXN 200001

int n, m, a[MAXN], b[MAXN];
std::priority_queue<int> q1;
std::priority_queue<int, std::vector<int>, std::greater<int> > q2;

int main() {
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
    for (int i = 1; i <= m; ++i) scanf("%d", &b[i]);
    int now = 1, cnt = 0;
    for (int i = 1; i <= b[now]; ++i) {
        q1.push(a[i]);
        while (i == b[now]) {
            ++cnt;
            while(q1.size() >= cnt) {
                int x = q1.top(); q1.pop();
                q2.push(x);
            }
            int ans = q2.top();
            q1.push(ans), q2.pop();
            printf("%d
", ans);
            ++now;
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/poi-bolg-poi/p/13563835.html