洛谷堆P1801 黑匣子_NOI导刊2010提高(06)

Posted DEVILK

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷堆P1801 黑匣子_NOI导刊2010提高(06)相关的知识,希望对你有一定的参考价值。

【题目描述:】

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

命令只有两种:

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

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

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

现在要求找出对于给定的命令串的最好的处理方法。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)个元素被放进了Black Box里后就出现一个GET命令。例如上面的例子中u=(l,2,6,6)。输入数据不用判错。

【输入格式:】

第一行,两个整数,M,N。

第二行,M个整数,表示A(l)…A(M)。

第三行,N个整数,表示u(l)…u(N)。

【输出格式:】

输出Black Box根据命令串所得出的输出串,一个数字一行。

技术分享图片
输入样例#17 4
3 1 -4 2 8 -1000 2
1 2 6 6
输出样例#13
3
1
2
输入输出样例

 

 

【算法分析:】

开两个堆,一个大根堆,一个小根堆,类似于“中位数”那道题

把每一个要求加入Black_Box的元素放入小根堆,然后把堆顶元素弹出后放到大根堆

这时如果小根堆的堆顶比大根堆的堆顶小,就交换两个堆的堆顶元素,

  直到小根堆的堆顶比大根堆的堆顶元素大,或者小根堆已空

这时大根堆的堆顶元素就是第i小的值

 

【代码:】

  1 //黑匣子_NOI导刊2010提高
  2 #include<iostream>
  3 #include<cstdio>
  4 using namespace std;
  5 
  6 const int MAXN = 200000 + 1;
  7 
  8 int n, m, a[MAXN], u[MAXN];
  9 
 10 int h1_size, h2_size;
 11 int h1[MAXN], h2[MAXN];
 12 
 13 void push1(int x) {
 14     h1[++h1_size] = x;
 15     int now = h1_size, next;
 16     while(now > 1) {
 17         next = now >> 1;
 18         if(h1[now] < h1[next])
 19             swap(h1[now], h1[next]);
 20         else break;
 21         now = next;
 22     }
 23 }
 24 int pop1() {
 25     int ret = h1[1];
 26     h1[1] = h1[h1_size--];
 27     int now = 1, next;
 28     while((now << 1) <= h1_size) {
 29         next = now << 1;
 30         if(next < h1_size && h1[next|1] < h1[next]) next |= 1;
 31         if(h1[now] > h1[next])
 32             swap(h1[now], h1[next]);
 33         else break;
 34         now = next;
 35     }
 36     return ret;
 37 }
 38 
 39 void push2(int x) {
 40     h2[++h2_size] = x;
 41     int now = h2_size, next;
 42     while(now > 1) {
 43         next = now >> 1;
 44         if(h2[now] > h2[next])
 45             swap(h2[now], h2[next]);
 46         else break;
 47         now = next;
 48     }
 49 }
 50 int pop2() {
 51     int ret = h2[1];
 52     h2[1] = h2[h2_size--];
 53     int now = 1, next;
 54     while((now << 1) <= h2_size) {
 55         next = now << 1;
 56         if(next < h2_size && h2[next|1] > h2[next]) next |= 1;
 57         if(h2[now] < h2[next])
 58             swap(h2[now], h2[next]);
 59         else break;
 60         now = next;
 61     }
 62     return ret;
 63 }
 64 
 65 int read() {
 66     int x = 0, f = 1;
 67     char ch = getchar();
 68     while(ch < 0 || ch > 9) {
 69         if(ch == -) f = -1;
 70         ch = getchar();
 71     }
 72     while(ch >= 0 && ch <= 9) {
 73         x = (x << 3) + (x << 1) + ch - 48;
 74         ch = getchar();
 75     }
 76     return x * f;
 77 }
 78 void write(int x) {
 79     if(x < 0) {
 80         putchar(-);
 81         x = -x;
 82     }
 83     if(x > 9) write(x / 10);
 84     putchar(x % 10 + 48);
 85 }
 86 
 87 int main() {
 88     n = read(), m = read();
 89     for(int i = 1; i <= n; i++) a[i] = read();
 90     for(int i = 1; i <= m; i++) u[i] = read();
 91     for(int i = 1; i <= m; i++) {
 92         for(int j = u[i - 1] + 1; j <= u[i]; j++) push1(a[j]);
 93         push2(pop1());
 94         while(h1_size > 0 && h1[1] < h2[1]) {
 95             int x1 = pop1(), x2 = pop2();
 96             push1(x2), push2(x1);
 97         }
 98         write(h2[1]);
 99         putchar(\n);
100     }
101 }

 

以上是关于洛谷堆P1801 黑匣子_NOI导刊2010提高(06)的主要内容,如果未能解决你的问题,请参考以下文章

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

题解 P1801 黑匣子_NOI导刊2010提高(06)

黑匣子_NOI导刊2010提高(06)

堆or优先队列(洛谷1801 黑匣子_NOI导刊2010提高(06))

treap

NOI导刊2010提高(06) 黑匣子