当前位置:首页 > 数据结构 > > 正文
SSOJ2278黑匣子
711+

题目大意:一个数列,一次放入Box,放入b[j]个后,回答第j小的是多少。

题目描述

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

命令只有两种:

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

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

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

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

编号 命令 i 黑匣子内容 输出
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

现在要求找出对于给定的命令串的最好的处理方法。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根据命令串所得出的输出串,一个数字一行。

样例输入

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

样例输出

3
3
1
2

提示

对于30%的数据,M≤5000;

对于50%的数据,M≤10000;

对于70%的数据,M≤100000;

对于100%的数据,M≤200000。

解题思路

本题可以用堆、线段树、树状数组+离散化等实现。

程序实现

堆实现:两个优先队列,前一个大的在top,后一个小的在top;前面的堆先放入1个,保证里面刚刚好只有i个(一开始i=1,输出第i小);之和如果没有放完b[i]个数,就放入后面的堆,放的过程中,保存前一个是最小的i个,即如果发现放入的数字比前一个的top要小,则把前一个的top放入后一个,将新数放入前一个堆;放够b[i]个数后,输出前一个的top,因为那是最小的i个数中的最大值;那么下一次输出的是第i+1小,前一个堆不足i+1个,可以从后一个对中取最小的放过去,如果后一个对没有数,就从数列中放进去。

线段树做法:动态开点可以避免爆空间,因为只有n次单点修改。依次放入数列中的数,放够b[j]个就二分查找第k个数(区间),需要注意线段区间不能用int了!

树状数组:离散化后,可以用树状数组统计前i个数出现次数之和,二分树状数组寻找第k小的数。

不会做到的话,可以暴力40分,每次回答对a数组前面b[j]个数进行排序,然后输出a[i],时间复杂度O(mnlog2n)。

暴力50分:快排查找第k小的数,复杂度是O(n)的,因为找到分界点后,第k小的数只会在其中一半,n+n/2+n/4+…+1不超过n*2。

暴力50分:其实用插入排序就行,左边有序,插入排序的复杂度是O(n)的!

更多
SSOJ2278黑匣子:等您坐沙发呢!

发表评论

😉😐😡😈🙂😯🙁🙄😛😳😮mrgreen.png😆💡😀👿😥😎😕

快捷键:Ctrl+Enter