//7977992 vrs 1442 Accepted 516K 125MS C 1930B 2010-12-07 13:26:53
//1142 黑盒数字 优先队列(大根堆+小根堆)
//这题看了别人的解题报告才弄出来的,感觉这里两个堆操作很巧妙
//维护两个优先队列,大根堆,小根堆,大根堆保存当前最小的i-1个数,并把i到u[p]个数放到小跟堆里,那么
//小根堆的最小值就是当前状态的第i小元素
//注意到一点,c不支持函数的按引用调用 &
#include<stdio.h>
#define bool int
#define MAXNUM 30005
long minqu[MAXNUM];
long maxqu[MAXNUM];
int n1,n2;
//不支持按引用调用,所以用指针实现
void swap(long *a,long *b)
{
long temp=*a; *a=*b; *b=temp;
}
void InsertMin(long data)
{
long father,son;
n1++;
minqu[n1]=data;
son=n1;
while(son>1)
{
father=son/2;
if(minqu[father]>minqu[son])
swap(&minqu[father],&minqu[son]);
else
break;
son=father;
}
}
void InsertMax(long data)
{
long father,son;
n2++;
maxqu[n2]=data;
son=n2;
while(son>1)
{
father=son/2;
if(maxqu[father]<maxqu[son])
swap(&maxqu[father],&maxqu[son]);
else
break;
son=father;
}
}
bool IsEmptyMin()
{
if(n1==0)
return 1;
else
return 0;
}
bool IsEmptyMax()
{
if(n2==0)
return 1;
else
return 0;
}
int TopMin()
{
return 1;
}
int TopMax()
{
return 1;
}
void PopMin()
{
int father,son;
swap(&minqu[1],&minqu[n1]);
n1--;
father=1;
while(father<=n1/2)
{
son=father*2;
if(son+1<=n1 && minqu[son]>minqu[son+1])
son++;
if(minqu[father]>minqu[son])
swap(&minqu[father],&minqu[son]);
else
break;
father=son;
}
}
void PopMax()
{
int father,son;
swap(&maxqu[1],&maxqu[n2]);
n2--;
father=1;
while(father<=n2/2)
{
son=father*2;
if(son+1<=n2 && maxqu[son]<maxqu[son+1])
son++;
if(maxqu[father]<maxqu[son])
swap(&maxqu[father],&maxqu[son]);
else
break;
father=son;
}
}
int main()
{
int M,N;
int i,j,k;
long a[30005];
long u[30005];
n1=n2=0;
scanf("%d%d",&M,&N);
for(i=1;i<=M;i++)
scanf("%ld",&a[i]);
for(i=1;i<=N;i++)
scanf("%ld",&u[i]);
i=1;u[0]=0;
for(j=1;j<=N;j++)
{
while(i<=u[j])
InsertMax(a[i++]);
for(k=u[j]-u[j-1];k>0;k--)
{
InsertMin( maxqu[TopMax()] );
PopMax();
}
printf("%ld\n", minqu[TopMin()] );
// 这里把TopMin()重新压进Max堆里很重要,这样就保证前i小个数一定留在Max堆里
InsertMax( minqu[TopMin()] );
PopMin();
}
return 0;
}