题目
简化题意
给你一堆数,每次让你求前多少个数中的第 (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;
}