Black Box_双优先队列

Black Box

TimeLimit: 1000ms  MemoryLimit:10000KB

64-bit integer IO format:%lld

Problem Description

Our Black Box represents a primitive database. It can save an integer array and has a special i variable. At the initial moment Black Box is empty and i equals 0. This Black Box processes a sequence of commands (transactions). There are two types of transactions:

ADD (x): put element x into Black Box; 
GET: increase i by 1 and give an i-minimum out of all integers containing in the Black Box. Keep in mind that i-minimum is a number located at i-th place after Black Box elements sorting by non- descending.

Let us examine a possible sequence of 11 transactions:

Example 1

N Transaction i Black Box contents after transaction Answer
      (elements are arranged by non-descending)
1 ADD(3)      0 3
2 GET         1 3                                    3
3 ADD(1)      1 1, 3
4 GET         2 1, 3                                 3
5 ADD(-4)     2 -4, 1, 3
6 ADD(2)      2 -4, 1, 2, 3
7 ADD(8)      2 -4, 1, 2, 3, 8
8 ADD(-1000)  2 -1000, -4, 1, 2, 3, 8
9 GET         3 -1000, -4, 1, 2, 3, 8                1
10 GET        4 -1000, -4, 1, 2, 3, 8                2
11 ADD(2)     4 -1000, -4, 1, 2, 2, 3, 8   

It is required to work out an efficient algorithm which treats a given sequence of transactions. The maximum number of ADD and GET transactions: 30000 of each type.

Let us describe the sequence of transactions by two integer arrays:

1. A(1), A(2), ..., A(M): a sequence of elements which are being included into Black Box. A values are integers not exceeding 2 000 000 000 by their absolute value, M <= 30000. For the Example we have A=(3, 1, -4, 2, 8, -1000, 2).

2. u(1), u(2), ..., u(N): a sequence setting a number of elements which are being included into Black Box at the moment of first, second, ... and N-transaction GET. For the Example we have u=(1, 2, 6, 6).

The Black Box algorithm supposes that natural number sequence u(1), u(2), ..., u(N) is sorted in non-descending order, N <= M and for each p (1 <= p <= N) an inequality p <= u(p) <= M is valid. It follows from the fact that for the p-element of our u sequence we perform a GET transaction giving p-minimum number from our A(1), A(2), ..., A(u(p)) sequence.

Input

Input contains (in given order): M, N, A(1), A(2), ..., A(M), u(1), u(2), ..., u(N). All numbers are divided by spaces and (or) carriage return characters.

Output

Write to the output Black Box answers sequence for a given sequence of transactions, one number each line.

SampleInput

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

SampleOutput

3
3
1
2

搞两个优先队列, 分别为 最大堆 和 最小堆, 目的是 在 n 个 数里, 获得第几大数。code:

#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
void solve( int, int );

int main(void)
{
    //freopen( "d://test.txt", "rw+", stdin );
    int n, t;
    while( scanf( "%d%d", &n, &t ) != EOF ){
        solve( n, t );
    }
    return 0;
}

void solve( int n, int t )
{
    int *_m = new int [ n+1 ];
    int num;
    priority_queue < int, vector< int >, greater <int> > pri_min;
    priority_queue < int, vector< int >, less <int> > pri_max;
    for( int i=0; i < n; ++ i ){
        scanf( "%d", _m+i );
    }

    for( int i=1, j=0; t --; ++ i ){
        scanf( "%d", &num );
        // 快速 填充到指定数目的数
        while( pri_max.size()+pri_min.size() < num ){
            pri_min.push( _m[ j ++ ] );
        }
        // 快速 填充 到最大堆, 使最大堆数目为 i
        while( pri_max.size() < i ){
            pri_max.push( pri_min.top() );
            pri_min.pop();
        }
        // 交换 最大堆 和 最小堆 数据, 直到符合情况
        while( pri_min.size() && pri_max.top() > pri_min.top() ){
            num = pri_max.top();
            pri_max.pop();
            pri_max.push( pri_min.top() );
            pri_min.pop();
            pri_min.push( num );
        }
        printf( "%d\n", pri_max.top() );
    }

    delete [] _m;
}

时间: 2024-10-11 02:07:24

Black Box_双优先队列的相关文章

用“双优先队列”方法解决双/多指标的规划问题

PS:本文要解决的问题不算难度很大的问题,但"双优先队列"的方法是以前没有见过的,昨天睡觉突然想到的,以时间Ο(logn),空间O(n)的较好代价解决一类问题,记录一下. 问题抽象: 算法的设计中常会出现这种需求,一个对象有多种比较策略,而不同的比较往往会产生矛盾,目的是在一项指标的约束下实现另一指标的最优化. 描述的云里雾里,其实例子比较好理解,比方说,KFC的外卖小哥们每人有一个电驴子,不同的剩余电量不同,远距离的单需要电多的车子去送,而派出小哥剩的电越多,成本就越高(这个好像没道

LeetCode----IPO「贪心/优先队列」

题目描述 假设 力扣(LeetCode)即将开始其 IPO.为了以更高的价格将股票卖给风险投资公司 力扣 希望在 IPO 之前开展一些项目以增加其资本. 由于资源有限,它只能在 IPO 之前完成最多 k 个不同的项目. 帮助 力扣 设计完成最多 k 个不同项目后得到最大总资本的方式. 给定若干个项目.对于每个项目 i,它都有一个纯利润 Pi,并且需要最小的资本 Ci 来启动相应的项目. 最初,你有 W 资本.当你完成一个项目时,你将获得纯利润,且利润将被添加到你的总资本中. 总而言之,从给定项目

redis 学习 四 队列

<?php /** * redis实战 * * 利用列表list实现简单队列 * * @example php cache.php */ header('content-type:text/html;chaeset=utf-8'); $redis = new \Redis(); $redis->connect('127.0.0.1', 6379); // 进队列 $userId = mt_rand(000000, 999999); $redis->rpush('QUEUE_NAME',j

构建队列,数组版本

队列作为基本的数据结构,是每个coder所必须掌握的. 队列在逻辑上就像是一条打饭的长队,排在前面的先打到饭(先进先出). 这里用一个数组用以构造一个队列,并设置两个指向,head指向队首,tail指向队尾,初始状态是head与tail指向同一位置(队列为空) 队列有两个操作:入队与出队. 1.入队:对比打饭排队的场景,新来的人排在后面,这是队尾tail需向后移一位. 2.出队:已经打好饭的人就可以出去了,这时队头也需向后移一位,让后面的人成为队头. 注意: 当head与tail都移到数组末端,

链队列代码及应用

链队列代码 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #define OK 1 #define ERROR 0 #define OVERFLOW -2 #define TRUE 1 #define FALSE 0 typedef int Status; typedef int ElemType; typedef struct Qnode{ int

caffe数据读取的双阻塞队列说明

caffe的datareader类中 class QueuePair { public: explicit QueuePair(int size); ~QueuePair(); BlockingQueue<T*> free_; BlockingQueue<T*> full_; DISABLE_COPY_AND_ASSIGN(QueuePair); }; 这个就是双阻塞队列,先将free队列填充到最大长度,然后按照如下规则: 1,每当生产者push时,先将full队列pop,如果fu

线性结构的常见应用之一 队列

定义:一种可以实现"先进先出"的存储结构 分类 链式队列 --  用链表实现 静态队列 --  用数组实现 静态队列通常都必须是循环队列 循环队列的讲解: 1.静态队列为什么必须是循环队列 2.循环队列需要几个参数来确定   需要两个参数来进行确定:front   rear 3.循环队列各个参数的含义 2个参数在不同的场合有不同的含义 建议初学者先记住,后面再想 1).队列初始化 front 和 rear 的值都是零 2).队列非空 front 代表的是队列的第一个元素 rear 代表

阻塞队列和生产者-消费者模式

阻塞队列提供了可阻塞的put和take方法.如果队列满了put将阻塞到有空间可用,如果队列为空,take将阻塞到有元素可用.队列可以是有界和无界的,无界的队列put将不会阻塞. 阻塞队列支持生产者消费者模式,该模式将找出需要完成的工作,和执行工作分开.生产者-消费者模式能简化开发过程,因为消除了生产者和消费者之间的代码依赖性,此外,该模式还将生产数据的过程和使用数据的过程解耦开来. 在基于阻塞队列构建的生产者-消费者设计中个,当数据生成时,生产者把数据放入队列,当消费者处理数据时,将从队列中获取

MQ队列管理器搭建(一)

多应用单MQ使用场景 如上图所示,MQ独立安装,或者与其中一个应用同处一机.Application1与Application2要进行通信,但因为跨系统,所以引入中间件来实现需求. Application1需要连接MQ,并将消息放入队列Queue中,Application2同样连接MQ,监听在Queue队列上,一旦发现有消息进入则取出该消息进行处理. 下面将给出创建队列管理器和队列的示例: 定义队列管理器名称为Qm1,本地队列名称为Queue,服务器连接通道CHAN_SERVER_CON,监听端口