题目描述

Black Box是一种原始的数据库。它可以储存一个整数数组,还有一个特别的变量i。最开始的时候Black Box是空的.而i等于0。这个Black Box要处理一串命令。

命令只有两种:

ADD(x):把x元素放进BlackBox;

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

记住:第i小的数,就是Black Box里的数的按从小到大的顺序排序后的第i个元素。例如:

我们来演示一下一个有11个命令的命令串。(如下图所示)

现在要求找出对于给定的命令串的最好的处理方法。ADD和GET命令分别最多200000个。现在用两个整数数组来表示命令串:

1.A(1),A(2),…A(M):一串将要被放进Black Box的元素。每个数都是绝对值不超过2000000000的整数,M$200000。例如上面的例子就是A=(3,1,一4,2,8,-1000,2)。

2.u(1),u(2),…u(N):表示第u(j)个元素被放进了Black Box里后就出现一个GET命令。例如上面的例子中u=(l,2,6,6)。输入数据不用判错。

输入输出格式

输入格式:

第一行,两个整数,M,N。

第二行,M个整数,表示A(l)

……A(M)。

第三行,N个整数,表示u(l)

…u(N)。

输出格式:

输出Black Box根据命令串所得出的输出串,一个数字一行。

输入输出样例

输入样例#1:

7 4
3 1 -4 2 8 -1000 2
1 2 6 6

输出样例#1:

3
3
1
2

说明

对于30%的数据,M≤10000;

对于50%的数据,M≤100000:

对于100%的数据,M≤200000。

思路:不难想到求第i小需要堆排序。

难点:难道每输出一个数,就要维护堆后重新堆排一遍?

机关(优化):只需求第i小的(即对于第i小的这个元素之前是否按顺序排好无要求)。

分析:堆的一个特点是只知最大(小)的那个元素,剩余位置较混乱;这也是它快的一个原因。

   【故求第i小,则可以建一个含i个元素的大根堆,堆顶即为所求】。

   而i个之外的元素可以放在另一个【小根堆】中,【以便向大根堆中补给】。

难点:随着输入数的增多,第i小的值会不断变化。

   先把输入的数据都输完了,才输要求输出的数据;如何做到随时向那个大根堆中补给适当的数?

思路:只需要将输入的数存入一个数组,就可以做到适时输入一样的效果,方便地取用。

于是诞生了很快的代码(n·logn):

#include<iostream>
#include<cstdio>
using namespace std;
int n,m,xnt1,xnt2,s=1;
long long c,hp1[200005],hp2[200005],a[200005];//hp1为那个小根堆,hp2为那个大根堆
void pus1(long long a)
{xnt1++;hp1[xnt1]=a;int now=xnt1;while(now>1){int tp=now/2;if(hp1[tp]>hp1[now])swap(hp1[tp],hp1[now]);else break;now=tp;}
}
void pus2(long long a)
{xnt2++;hp2[xnt2]=a;int now=xnt2;while(now>1){int tp=now/2;if(hp2[tp]<hp2[now])swap(hp2[tp],hp2[now]);else break;now=tp;}
}
long long del1()
{long long res=hp1[1];hp1[1]=hp1[xnt1];xnt1--;int now=1;while(now*2<=xnt1){int tp=now*2;if(tp<xnt1&&hp1[tp+1]<hp1[tp])tp++;if(hp1[tp]<hp1[now])swap(hp1[tp],hp1[now]);else break;now=tp;}return res;
}
long long del2()
{long long res=hp2[1];hp2[1]=hp2[xnt2];xnt2--;int now=1;while(now*2<=xnt2){int tp=now*2;if(tp<xnt2&&hp2[tp+1]>hp2[tp])tp++;if(hp2[tp]>hp2[now])swap(hp2[tp],hp2[now]);else break;now=tp;}return res;
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%lld",&a[i]);for(int i=1;i<=m;i++){scanf("%lld",&c);for(;s<=c;s++){if(!hp2[1]){pus2(a[s]);continue;}if(a[s]>=hp2[1])pus1(a[s]);else{if(xnt2==i)//原来xnt2是i-1,当已经进入过一个元素后,再要进入,就需调整pus1(del2());//把原来的堆顶挤入hp1中pus2(a[s]);}}if(xnt2<i)pus2(del1());//从hp1中取出一个放入hp2printf("%lld\n",hp2[1]);}
}

转载于:https://www.cnblogs.com/Narh/p/8032340.html

堆-动态的排序(洛谷1801-黑匣子)相关推荐

  1. 升序堆和降序堆(优先队列) 洛谷1801

    1 // 洛谷1801 2 // 一个升序堆,一个降序堆 3 // 降序堆维护序列的前i个最小值 4 // 插如元素的时候,如果x小于降序堆最大值,则替换,并将最大值插入升序堆:否则,直接插入升序堆 ...

  2. 洛谷P1801 黑匣子 双堆套路的使用

    题意 题目链接 题解 这道题本可以用Treap暴力求解出来,但是不够优雅,因为没有充分利用到题目中给的条件,那就是要求的ithithith小的值的iii是单调递增的. 我们用两个堆来维护,大顶堆和小顶 ...

  3. 洛谷P1801 黑匣子

    题目描述 Black Box 是一种原始的数据库.它可以储存一个整数数组,还有一个特别的变量 ii.最开始的时候 Black Box 是空的.而 i=0i=0.这个 Black Box 要处理一串命令 ...

  4. 洛谷 [P1801] 黑匣子

    这道题是一道splay裸题,然而身为蒟蒻的我并不会,所以这道题我维护的是一个大根堆与一个小根堆结合起来的类似沙漏的结构. 本题难点在于询问的不是最大最小值,而是第K小值,所以我们想到了维护这样两个堆, ...

  5. AC日记——双栈排序 洛谷 P1155

    双栈排序 思路: 二分图染+模拟: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1005 #define ...

  6. 洛谷 P2046 BZOJ 2007 海拔(NOI2010)

    题目描述 YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见,可以将YT市看作 一个正方形,每一个区域也可看作一个正方形.从而,YT城市中包括(n+1)×(n+1)个 ...

  7. 洛谷 深基 第4部分 基础数学与数论(19-21课)

    洛谷 深基 第4部分 基础数学与数论  第19章 位运算与进制转换 P1143 进制转换 https://www.luogu.com.cn/problem/P1143 洛谷P1143 进制转换的Pyt ...

  8. 洛谷--橙色百道DP总结

    最近刷完了洛谷橙色DP大约一百道,算是发现了一些套路,就部分题目做一些总结. 大概分为三类 第一类,九大背包及其衍生 第二类,经典DP模型,如LCS,LIS等 第三类,实际问题背景的普通,环形,树上D ...

  9. 洛谷P2085ssl1411OJ1370-最小函数值【堆,贪心】

    前言 有一个东西卡了我一会 折叠N*或N+ 正整数集 (由全体正整数组成的集合) N*:={1,2,3,-,n,-} 题目 洛谷P2085 OJ1370 给出n个ai,bi,ci.定义一个函数 fi( ...

最新文章

  1. conda安装qiime2-清华镜像源替换法解决安装失败
  2. Java专家系列:CPU Cache与高性能编程
  3. 再看Kafka Lag
  4. word2026第十套计算机二级,计算机二级第十套练习真题
  5. vb net的定时循环_.NET工具ReSharper:如何帮助Visual Studio用户?
  6. Atitit.事件机制 与 消息机制的联系与区别
  7. 亚马逊创始人贝佐斯离婚协议本周生效 前妻分得380亿美金
  8. ubuntu没有进入图形界面解决办法
  9. 在HFSS中用vbs脚本跑马灯?
  10. tensorflow.js基本使用 图标识别(八)
  11. UNet++ 论文翻译
  12. 停车场管理(C语言版)
  13. 如何linux删除文件夹,Linux系统下如何删除文件夹
  14. [MAC 苹果电脑] [装双系统] “苹果电脑装Windows双系统”讲解
  15. QQ9.0需要安装两个插件
  16. 解决各大浏览器下载文件,文件名中文乱码的问题
  17. windows设备管理器_如何打开Windows设备管理器?
  18. 你创建微信公众账号了吗?别闲着,来做微信营销吧
  19. 新媒体运营——客户沟通方式
  20. Java对dat文件内容进行查询_java读写dat文件

热门文章

  1. linux环境手动编译安装Nginx实践过程 附异常解决
  2. Windows 下 Redis 服务无法启动,错误 1067 进程意外终止解决方案
  3. nginx 反向代理时丢失端口的解决方案(转)
  4. element ui 弹出组件的遮罩层在弹出层的上面的解决方法
  5. webpack 运行提示“The ‘mode‘ option has not been set”的原因和解决方法
  6. 关于java.sql.SQLRecoverableException: Closed Connection异常的解决方案(转)
  7. 具有左,中或右对齐项的Bootstrap NavBar
  8. 如何在Bash脚本中将Heredoc写入文件?
  9. 基本数据类型包装类的使用与转换
  10. java 文本框输入监听事件_JAVA GUI 事件监听事件 详解 和 案例.