zoukankan      html  css  js  c++  java
  • Luogu1801 黑匣子 堆

    传送门

    题意:给出两种命令:

    ADD(x):把 x 元素放进 Black Box;

    GET:i 加 1,然后输出 Black Box 中第 i 小的数。

    输出每次GET操作的结果。

    题解:
    注意到每次求的第k小中,k从1开始递增。则维护一个大根堆和一个小根堆,大根堆里记录前K小的数字,小根堆里记录其他的数字。
    这样构造有一个性质:
    1.大根堆里最大的数即为当前数组中的第K小。
    在遇到GET操作之前,对于每个待加入的数字,判断其是否为前K小,若是,则加入到大根堆中,并把大根堆中最大的数放到小根堆中;否则直接加入小根堆。
    GET操作:取出小根堆里面最小的数即为答案,再将这个数取出加入到大根堆中,满足上面的性质。

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int MAXN = 200005, MAXM = 200005;
    
    int a[MAXN];
    
    inline int read(){
    	int k = 0, f = 1; char ch = getchar();
    	while(ch < '0' || ch > '9'){if(ch == '-') f = -1; ch = getchar();}
    	while(ch >= '0' && ch <= '9'){k = k * 10 + ch - '0'; ch = getchar();}
    	return k * f;
    }
    
    priority_queue <int> q1, q2;
    //q1为小根堆,q2为大根堆 
    
    int main(){
    	freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
    	int m = read(), n = read();
    	for(int i = 1; i <= m; i++){
    		a[i] = read();
    	}
    	
    //	for(int i = 1; i <= m; i++){
    //		printf("%d ", -q1.top());
    //		q1.pop();
    //	}
    	
    	int now = 0, kth = 0, cur = 0;
    	for(int i = 1; i <= n; i++){
    		int k = read();
    		while(now < k){
    			now++;
    			if(!q2.empty()){
    				int x = q2.top();
    				if(x > a[now]){
    					q2.pop();
    					q1.push(-x);
    					q2.push(a[now]);
    				}
    				else{
    					q1.push(-a[now]);
    				}
    			}
    			else{
    				q1.push(-a[now]);
    			}
    			
    		}
    		kth++;
    		int q1min = -q1.top(); q1.pop();
    		q2.push(q1min);
    		printf("%d
    ", q1min);
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    机械键盘与选购技巧
    计算机科学与技术专业的知识架构
    加法器
    计算机底层逻辑电路
    小数在计算机的表示
    整数在计算机里的表示
    Core ML 机器学习
    MapFileParser.sh: Permission denied
    iOS开发创建UI的耗时操作处理
    iOS application/json上传文件等
  • 原文地址:https://www.cnblogs.com/asdf1229/p/13886127.html
Copyright © 2011-2022 走看看