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

可以使用一种叫做对顶堆的东西,对顶堆是在线维护第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. centos 複製時顯示進度的指令 pv

    Pipe Viewer 的简称pv:意思是通过管道显示数据处理进度的信息.这些信息包括已经耗费的时间,完成的百分比(通过进度条显示),当前的速度,全部传输的数据,以及估计剩余的时间. yum inst ...

  2. Codeforces Round #178 (Div. 2) B .Shaass and Bookshelf

    Shaass has n books. He wants to make a bookshelf for all his books. He wants the bookshelf's dimensi ...

  3. 课程的正确步调——Leo鉴书74

    <Leo鉴书(第1辑)>已登陆百度阅读.今后还将不断更新,免费下载地址:http://t.cn/RvawZEx 本人第一次站上讲台是1999年,那会儿从中关村回到天津,在一个给成人做计算机 ...

  4. MongoDB:分片(简介 & 自动分片 & 片键)

    分片(增加服务器,水平扩展)是MongoDB的扩展方式,通过分片能过增加更多的机器来应对不断增加的负载和数据,还不影响应用. [简介] 分片(sharding)是指将数据拆分,将其分散存在不同的机器上 ...

  5. MCE----Machine-check exception

    http://en.wikipedia.org/wiki/Machine_Check_Exception Machine-check exception From Wikipedia, the fre ...

  6. 4. 基本TCP套接字编程

    基本函数接口 socket函数 #include <sys/socket.h> int socket(int family, int type, int protocol); 成功时返回一 ...

  7. Aspose 直接插入SQL Server DataTalbe

    原文链接:http://www.cnblogs.com/hellohongfu/p/7362830.html 下面的代码可以根据excel文件,生成创建表的SQL,以及测试InsertSQL .方法将 ...

  8. Mybatis中的大于等于和小于等于

    mybatis中可以直接使用>或<:但是不能直接使用>=或<=; 第一种写法(1): 原符号 < <= > >= & ' " 替换符号 ...

  9. Tomcat版本是32位、64位问题

    最近遇到一个Tomcat windows安装版本是32位还是64位问题.由于一系列原因,已经无从知晓生产系统上的该程序是32位还是64位. 后来经过仔细查阅资料,得知: 1. tomcat 从6.0. ...

  10. Go语言的管道Channel用法

    本文实例讲述了Go语言的管道Channel用法.分享给大家供大家参考.具体分析如下: channel 是有类型的管道,可以用 channel 操作符 <- 对其发送或者接收值. ch <- ...