【题目描述:】
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根据命令串所得出的输出串,一个数字一行。
输入样例#: - - 输出样例#:
输入输出样例
【算法分析:】
开两个堆,一个大根堆,一个小根堆,类似于“中位数”那道题
把每一个要求加入Black_Box的元素放入小根堆,然后把堆顶元素弹出后放到大根堆
这时如果小根堆的堆顶比大根堆的堆顶小,就交换两个堆的堆顶元素,
直到小根堆的堆顶比大根堆的堆顶元素大,或者小根堆已空
这时大根堆的堆顶元素就是第i小的值
【代码:】
//黑匣子_NOI导刊2010提高
#include<iostream>
#include<cstdio>
using namespace std; const int MAXN = + ; int n, m, a[MAXN], u[MAXN]; int h1_size, h2_size;
int h1[MAXN], h2[MAXN]; void push1(int x) {
h1[++h1_size] = x;
int now = h1_size, next;
while(now > ) {
next = now >> ;
if(h1[now] < h1[next])
swap(h1[now], h1[next]);
else break;
now = next;
}
}
int pop1() {
int ret = h1[];
h1[] = h1[h1_size--];
int now = , next;
while((now << ) <= h1_size) {
next = now << ;
if(next < h1_size && h1[next|] < h1[next]) next |= ;
if(h1[now] > h1[next])
swap(h1[now], h1[next]);
else break;
now = next;
}
return ret;
} void push2(int x) {
h2[++h2_size] = x;
int now = h2_size, next;
while(now > ) {
next = now >> ;
if(h2[now] > h2[next])
swap(h2[now], h2[next]);
else break;
now = next;
}
}
int pop2() {
int ret = h2[];
h2[] = h2[h2_size--];
int now = , next;
while((now << ) <= h2_size) {
next = now << ;
if(next < h2_size && h2[next|] > h2[next]) next |= ;
if(h2[now] < h2[next])
swap(h2[now], h2[next]);
else break;
now = next;
}
return ret;
} int read() {
int x = , f = ;
char ch = getchar();
while(ch < '' || ch > '') {
if(ch == '-') f = -;
ch = getchar();
}
while(ch >= '' && ch <= '') {
x = (x << ) + (x << ) + ch - ;
ch = getchar();
}
return x * f;
}
void write(int x) {
if(x < ) {
putchar('-');
x = -x;
}
if(x > ) write(x / );
putchar(x % + );
} int main() {
n = read(), m = read();
for(int i = ; i <= n; i++) a[i] = read();
for(int i = ; i <= m; i++) u[i] = read();
for(int i = ; i <= m; i++) {
for(int j = u[i - ] + ; j <= u[i]; j++) push1(a[j]);
push2(pop1());
while(h1_size > && h1[] < h2[]) {
int x1 = pop1(), x2 = pop2();
push1(x2), push2(x1);
}
write(h2[]);
putchar('\n');
}
}