![在这里插入图片描述](https://img-blog.csdnimg.cn/20210302110347322.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NzkxNDg0,size_16,color_FFFFFF,t_70)
题解
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210302110939589.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NzkxNDg0,size_16,color_FFFFFF,t_70)
- 我们可以用对顶堆来维护一个有序的序列,如图我们只要维护大根堆中的元素是i-1个,那么小根堆的堆顶就是按升序排序后的第i个数,接下俩看两个操作
- 对于GET操作,先让i++,然后输出排序后的第i个数,但是题中给定的数组是先输出,后i++(看题),那么我们每次先输出right(小根堆)的堆顶,然后i++,那么left(大根堆)中的元素就应该加+1,我们只需要将小根堆的堆顶放入大根堆中即可维护
- 对于ADD操作,如果插入的这个a[i]>=right.top||left.empty(),那么我们直接放入小根堆中即可,因为我们不需要维护小根堆的大小,如果a[i]<right.top,那么我们就要将a[i]放入大根堆中,但是此时大根堆中的元素个数增加了,所以我们还要维护一下大根堆中元素的个数,那么就要将大根堆的堆顶放入小根堆中即可
代码
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int N = 3e4 + 10;
int n, m;
int a[N], b[N];
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
cin >> m >> n;
for (int i = 0; i < m; i++) cin >> a[i];
for (int i = 0; i < n; i++) cin >> b[i];
sort(b, b + n);
priority_queue<int> left;
priority_queue<int, vector<int>, greater<int>> right;
int i = 0, j = 0;
while (i < m || j < n) {
while (j < n && b[j] == i) {
cout << right.top() << endl;
left.push(right.top());
right.pop();
j++;
}
if (left.empty() || a[i] >= right.top()) right.push(a[i]);
else {
left.push(a[i]);
right.push(left.top());
left.pop();
}
i++;
}
return 0;
}