这道题是提高+省选-的难度,做出来的话对数据结构题目的理解会增加很多。

可以使用一种叫做对顶堆的东西,对顶堆是在线维护第n小的logn的算法。大概的思路是,假如我们要找的是第n小,我们就维护一个大小为n的(位于下方的)大顶堆,(位于上方的)小顶堆中每个元素都比大顶堆的大。在这道题中,n不变时每次有新的比他小的就把堆顶弹出到对顶(也就是小顶堆)的堆顶,每次n扩大的时候就从(上面的)小顶堆里取出堆顶放进大顶堆的堆顶……

但是看样子应该其他平衡树也是可以解决这个问题的。比如支持快速名次的splay?还有完全另一个维度复杂的主席树(区间第k大)。

这道题应该是对顶堆最简单了。但是明显是用别的数据结构更好,因为对顶堆的第n小只能慢慢变……这样真的不如splay……(当然啦!splay这么复杂,你怎么不用主席树呢?主席树还区间第k大呢?)

Pdalao说了一个,可以用BST来维护,每个节点维护左子树的名次,那么找k的时候就可以判断是进入左子树还是右子树了,陷入思考……其实还是要旋转来保持平衡树的特性……

真实的递归学习法,一个两个都不会。


动态维护第k小也可以交给各类平衡树去完成。 而且k还可以不断改。

对顶堆用来维护一种顶堆只会不断扩大的情形非常方便。和之前的动态求中位数一个道理。

这里我们根据题目命名为“黑匣子堆”:注意每次顶堆扩大时,假如底堆有元素则优先从底堆获取。

#include<bits/stdc++.h>
using namespace std; struct Black_Box_Heap{
//top_heap has the min element,bottom heap has the max element priority_queue<int,vector<int>,less<int> > top_heap;
priority_queue<int,vector<int>,greater<int> > bottom_heap; int i; Black_Box_Heap(){i=;} void add(int value){
if(top_heap.size()<=i){
top_heap.push(value);
}
else{
if(value<top_heap.top()){
bottom_heap.push(top_heap.top());
top_heap.pop();
top_heap.push(value);
}
else{
bottom_heap.push(value);
}
}
} int get(){
int t=top_heap.top();
i++;
while(top_heap.size()<=i&&!bottom_heap.empty()){
top_heap.push(bottom_heap.top());
bottom_heap.pop();
}
return t;
}
}bbh; int a[]; int main(){
int m,n;
scanf("%d%d",&m,&n);
for(int i=;i<=m;i++){
scanf("%d",&a[i]);
} int j=;
for(int i=;i<=n;i++){
int u;
scanf("%d",&u);
while(u>=j){
bbh.add(a[j]);
j++;
} printf("%d\n",bbh.get());
}
}

洛谷 - P1801 - 黑匣子 - 对顶堆的更多相关文章

  1. 洛谷 P1801 黑匣子_NOI导刊2010提高(06)(未完)

    P1801 黑匣子_NOI导刊2010提高(06) 题目描述 Black Box是一种原始的数据库.它可以储存一个整数数组,还有一个特别的变量i.最开始的时候Black Box是空的.而i等于0.这个 ...

  2. P1801 黑匣子[对顶堆]

    没错我就是专门找对顶堆练习题的.现在感觉对顶堆使用面有点狭窄.这道题由于我询问是随时间单调增的,而且数据比较友好,应该是插入几次就询问一下的.而中位数那题也是经常询问的.如果查询的东西不单调,或者查询 ...

  3. 洛谷 [P1801] 黑匣子

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

  4. 洛谷P1801 黑匣子

    题目传送门 分析:这题和另外一个题目中位数非常相似,有兴趣可以先看看,比这一题简单.首先暴力模拟还是别想了,估计30%的数据都有点悬.正解应该是用二叉堆.但是如果用一个堆当然不方便,所以建两个堆,一个 ...

  5. 洛谷 P1801 黑匣子_NOI导刊2010提高(06) 题解

    昨晚恶补了一下二叉堆的内容 然后就找了几个二叉堆的题来做awa 然后发现用二叉堆做这题复杂度是O(nlogn) 但是有O(n)的解法 (某大佬这么说) 思路大概就是: 利用一个大根堆一个小根堆来维护第 ...

  6. [洛谷P1801]黑匣子_NOI导刊2010提高(06)

    题目大意:两个操作:向一个可重集中加入一个元素:询问第$k$大的数($k$为之前询问的个数加一) 题解:离散化,权值线段树直接查询 卡点:无 C++ Code: #include <cstdio ...

  7. 洛谷 P1801 黑匣子_NOI导刊2010提高(06)

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

  8. 洛谷 P1801 黑匣子 题解

    题面 离线处理: 大体思路就是将数组排序,然后对于第k次询问把不可行的数打上标记,然后从头开始寻找第k个没打标记的点的值(排序后的数组保证了它是第k小的). 实现方法:首先离散化原始数组,得到数组fi ...

  9. 【洛谷P1801】黑匣子

    黑匣子 题目链接 看到题解中“维护两个堆”,突然想到了这道题的解法 维护两个堆:大根堆h1, 小根堆h2 大根堆里的是最小的i个值,小根堆里是剩下的值 每Add一个值时 插入到小根堆中, 再比较小根堆 ...

随机推荐

  1. BUPT复试专题—分数加法(2014网研)

    题目描述 求2^-a + 2^-b,其中a和b均为正整数,结果用最简分数表示 输入 第一行为测试数据的组数T (1~400).请注意,任意两组测试数据之间相互独立的.每组测试数据一行,包含两个整数a和 ...

  2. Multi-company rules

    Object Name Domain 说明 Point of Sale Point Of Sale Order [('company_id', '=', user.company_id.id)] 指派 ...

  3. China Vis 2015 会议小结

    China Vis 2015  Paper有6个分会场.主要有 1.天气.气象.灾害可视化. 2.文本可视化应用: 3.树.网络.以及高维技术. 4.时空分析. 5.科学可视化与应用: 五个方面主题. ...

  4. javascript Array method总结

    0.创建 Javascript创建数组的基本方式有两种.第一种是使用Array构造函数. var colors = new Array(); var colors = new Array(20); v ...

  5. CSDN-markdown编辑器之从线上导入Markdown文件

      CSDN-markdown编辑器支持从线上导入Markdown文件的功能,假设你用其他支持Markdown的编辑器在网上写了博客文章或说明档,想公布到CSDN博客中,就能够使用本功能非常方便的完毕 ...

  6. BAT&注册表重定向劫持

    RunJS 常用引导,有时启动某个应用需要环境变量可以这样启动应用,会对启动的进程生效,即被继承 set PATH=D:\Developer\sdk\platform-tools;%PATH% D: ...

  7. 项目Alpha冲刺(团队8/10)

    项目Alpha冲刺(团队8/10) 团队名称: 云打印 作业要求: 项目Alpha冲刺(团队) 作业目标: 完成项目Alpha版本 团队队员 队员学号 队员姓名 个人博客地址 备注 221600412 ...

  8. Python调用C/Fortran混合的动态链接库--中篇

    接下来,介绍一个简单的例子,从fortran中传递并返回一维自定义结构体数组到python注意点:1.fortran新标准支持可分配数组作为变量传入并在subroutine或function分配后返回 ...

  9. C/C++语言中的位运算

    在计算机程序中,数据的位是可以操作的最小数据单位,理论上可以用“位运算”来完成所有的运算和操作. 一般的位操作是用来控制硬件的,或者做数据变换使用,但是,灵活的位操作可以有效地提高程序运行的效率.C语 ...

  10. sanic官方文档解析之streaming(流动,滚动)和class_based_views(CBV的写法)

    1,streaming(流媒体) 1.1请求流媒体 Sanic允许你通过流媒体携带请求数据,如下,当请求结束await request.stream.read()就会返回None,仅仅只有post请求 ...