题解【黑匣子_NOI导刊2010提高(06)】(洛谷P1801)

题目大意

给出一个长度为\(M\)序列\(A\),表示第\(i\)回合将\(A_i\)放入一个箱子中(共有\(M\)回合),再给出一个长度为\(N\)序列\(B\),表示在\(B_i\)回合执行一次\(Get\)操作。\(Get\)操作:\(k++\),然后输出箱子中第\(k\)大的元素;\(k\)初始为\(0\)

分析一下

  • 啊箱子就是堆啦
  • 假设正在进行第\(B_i\)回合,就是要将\(A_{B_i}\)放进箱子中,然后再输出箱子中第\(i\)小的元素。
  • 对于箱子中第\(i\)小的元素,其左边的元素(第\(i-1\cdots 1\)小)全部比其小,且依次变小,符合大根堆的特性;
  • 其右边的元素(第\(i +1\cdots M\)小)全部比其大,且依次变大,符合小根堆的特性。
  • 那么我们可以用一个大根堆与一个小跟堆来维护箱子里面的元素。将每次要求的答案放在小根堆(当然大根堆也可以)的堆顶。
  • 可以发现,大根堆中的元素个数始终为\(i-1\)

操作流程

  • 首先外循环枚举\(B\)序列。将\(A\)序列中的元素塞进大根堆中。
  • 维护大根堆中的元素只能有\(i-1\)个,即每当个数超出时,将大根堆的堆顶移至小根堆中。
  • 输出小根堆的堆顶(即答案)。因为这个答案已经贡献完了,所以再将其塞回至大根堆中。
posted @ 2018-07-17 13:13  JackHomes  阅读(176)  评论(0编辑  收藏  举报