二叉堆_POJ1442_Black Box

版权声明:本文为博主原创作品, 转载请注明出处! https://blog.csdn.net/solider98/article/details/84032393

点此打开题目页面

思路分析:

    建立最大堆pqmax 和最小堆pqmin, 动态维持pqmax中存储当前已读入的前i + 1小数字, pqmin存储其余数字即可, 基本上和求中位数的对顶堆算法是一致的, 具体参见如下AC代码:

//POJ1442_Black Box
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
const int MAXM = 3e5 + 5;
int A[MAXM], u[MAXM], M, N;
int main(){
	scanf("%d %d", &M, &N);
	for(int i = 1; i <= M; ++i) scanf("%d", &A[i]);
	for(int i = 1; i <= N; ++i) scanf("%d", &u[i]);
	priority_queue<int> pqmin, pqmax;//pqmax:最大堆, pqmin:最小堆
	pqmax.push(A[1]); int i = 0, j = 2, k = 1;
	if(u[1] == 1) cout << pqmax.top() << endl, ++i, ++k;
	//每次循环头检测之前pqmax.size() <= i + 1, 如果pqmax.size() < i + 1, 那么pqmin为空
	//且所有元素个数不超过j - 1的输出指令已经完成 
	for(; j <= M; ++j){
		if(pqmax.size() < i + 1){		
			pqmax.push(A[j]);
			if(k <= N && u[k] == j) cout << pqmax.top() << endl, ++i, ++k;
		}
		else{
			if(pqmax.top() > A[j]) pqmin.push(-pqmax.top()), pqmax.pop(), pqmax.push(A[j]);
			else pqmin.push(-A[j]);
			while(k <= N && u[k] == j){
				cout << pqmax.top() << endl, ++i, ++k;
				if(!pqmin.empty()) pqmax.push(-pqmin.top()), pqmin.pop();
			}			
		}
	} 	
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/solider98/article/details/84032393
Box