Black Box

POJ

题意:长度为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\n",q.top());
		Q.push(q.top());q.pop();
	}
    return 0;
}

posted on 2019-07-26 17:31  PPXppx  阅读(136)  评论(0编辑  收藏  举报