题意:长度为n的序列A,长度为m的查询序列B,对于每个查询B[i],求出序列A中前B[i]个数的第i小的值.((N,M<=30000))
分析:建立一个大根堆,一个小根堆,时刻保证大根堆中有最小的i-1个数,则此次查询的结果第i小的数就是小根堆的堆顶元素.大根堆的堆顶元素其实是候选答案,当新push进去的小根堆的堆顶小于大根堆的堆顶时,交换两个堆顶.
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
inline int read(){
int x=0,o=1;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')o=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*o;
}
const int N=30005;
int a[N],b[N];
priority_queue<int>Q;
priority_queue<int,vector<int>,greater<int> >q;
int main(){
int n=read(),m=read();
for(int i=1;i<=n;++i)a[i]=read();
for(int i=1;i<=m;++i)b[i]=read();
int now=1;
for(int i=1;i<=m;++i){
while(now<=b[i]){
q.push(a[now]);
if(!Q.empty()&&q.top()<Q.top()){
int cnt=q.top();
q.pop();q.push(Q.top());
Q.pop();Q.push(cnt);
}
++now;
}
printf("%d
",q.top());
Q.push(q.top());q.pop();
}
return 0;
}