P1801 黑匣子_NOI导刊2010提高(06)
    • 539通过
    • 1.2K提交
  • 题目提供者该用户不存在
  • 标签NOI导刊云端↑
  • 难度提高+/省选-
  • 时空限制1s / 128MB

 提交  讨论  题解  

最新讨论更多讨论

  • 啥情况?!!裸的bst也能ac…
  • 样例输入中少一个空格
  • 题面输出数据有问题
  • 请神牛帮忙看一看哪里错了!…
  • 题目中有单词打错了
  • 是否有问题

题目描述

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

命令只有两种:

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

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

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

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

洛谷P1801 黑匣子_NOI导刊2010提高(06)_数据

现在要求找出对于给定的命令串的最好的处理方法。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)个元素被放进了Blaek 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。

分析:这道题可以用treap秒掉啊,但是写起来比较麻烦,观察题目发现似乎可以用优先队列做,写起来又方便.但是有一个问题,就是我们每输出一个数就要先弹掉前面的所有数然后再添加回去,这样做的效率太低了,有没有一种方法只用输出队首元素即可呢?答案是有。我们可以维护一个递增的优先队列q1和递减的优先队列q2,并用一个变量cur记录我们要求第几小的元素.先遍历,每次都将元素添加进q2,如果q2的长度大于cur,那么就将队首元素弹出添加进q1,因为这个时候q2的其它部分是用不到的,这也就意味着我们将所有位置大于cur的元素都压进了q1,因为q1是递增的,所以队首元素就是我们要输出的(这里可以来一波意识流),输出后将其弹出,并继续添加进q2,因为这个元素可能对之后的结果有贡献。代码好像q1,q2打反了,不过不影响什么.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <functional>

using namespace std;

priority_queue<int> q1;
priority_queue<int, vector<int>, greater<int> >q2;

int m, n,a[200010],u[200010],cur = 0;

int main()
{
    scanf("%d%d", &m, &n);
    for (int i = 1; i <= m; i++)
        scanf("%d", &a[i]);
    for (int i = 1; i <= n; i++)
    {
        int t;
        scanf("%d", &t);
        u[t]++;
    }
    for (int i = 1; i <= m;i++)
    {
        q1.push(a[i]);
        if (q1.size() > cur)
        {
            q2.push(q1.top());
            q1.pop();
        }
    while (u[i])
        {
            u[i]--;
            printf("%d\n", q2.top());
            q1.push(q2.top());
            q2.pop();
            cur++;
        }
    }

    return 0;
}