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

可以使用一种叫做对顶堆的东西,对顶堆是在线维护第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. Classification and logistic regression

    logistic 回归 1.问题: 在上面讨论回归问题时.讨论的结果都是连续类型.但假设要求做分类呢?即讨论结果为离散型的值. 2.解答: 假设: 当中: g(z)的图形例如以下: 由此可知:当hθ( ...

  2. HDU 1003 Max Sum (动规)

    Max Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Su ...

  3. python实现的一个简单的网页爬虫

    学习了下python,看了一个简单的网页爬虫:http://www.cnblogs.com/fnng/p/3576154.html 自己实现了一个简单的网页爬虫,获取豆瓣的最新电影信息. 爬虫主要是获 ...

  4. c程序设计语言第一章2

    练习1.13编写一个程序,打印输入中单词长度的直方图.水平方向的直方图比较容易绘制,垂直方向的直方图则要困难些 #include <stdio.h> #include <stdlib ...

  5. HDU 2049 不容易系列之(4)——考新郎 (递推,含Cmn公式)

    不容易系列之(4)——考新郎 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  6. BusHelper

    https://github.com/eltld/-BusHelper https://github.com/eltld/BusLineSAX

  7. linux下DOS工具

    1.Hping3/Nping TCP/IP数据包生成工具,用于压力测试,安全审计 2.使用hping进行DOS攻击 命令:hping3 -c 10000 -d 120 -S -w 64 -p 80 - ...

  8. android经常使用正则工具类

    此类提供日常开发中经常使用的正则验证函数.比方:邮箱.手机号.电话号码.身份证号码.日期.数字.小数.URL.IP地址等.使用Pattern对象的matches方法进行整个字符匹配,调用该方法相当于: ...

  9. 我为什么不喜欢 CoreData

    我为什么不喜欢 CoreData   我一直不喜欢 Core Data,以前不太敢明目张胆地这么表达,现在收集到越来越多相关的信息,所以给大家分享一下,我为什么不喜欢 Core Data. Core ...

  10. wxpython中鼠标样式的获取与匹配

    在wxpython中定义有多种默认的鼠标样式,譬如:wx.CURSORCROSS wx.CURSORHAND等等, 此处按下不表,可以参考wxpython的samples里面自带的cursor例子 这 ...