正题
这题在维护第i大的值上运用了巧妙的方法。
我们用一个大根堆和一个小根堆来分别维护前i小的和剩余的,那么答案很明显,就是当前拥有前i小元素的大根堆的堆顶。我们每次把新的元素加入小跟堆,然后让大根堆和小根堆互换相斥元素。(就是小的往大根堆跑,大的往小跟堆跑)
代码<注意操作>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
priority_queue<int> h1;
priority_queue<int , vector<int> , greater<int> > h2;
int m,n;
int b[200010];
int a[200010];
int main(){
scanf("%d %d",&m,&n);
for(int i=1;i<=m;i++) scanf("%d",&b[i]);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int now=1;
int kk=0;
for(int i=1;i<=m;i++){
h2.push(b[i]);
while(a[now]==i){
h1.push(h2.top());
h2.pop();
while(h1.top()>h2.top() && !h1.empty() && !h2.empty()){
int t1=h1.top(),t2=h2.top();
h1.pop();h2.pop();
h1.push(t2),h2.push(t1);
}
printf("%d\n",h1.top());
now++;
}
}
}