首先,这道题让我们求每次的第i大值,而i是会移动的——那我们就可以理解为,我们需要知道第i大值和第i+1大值(请撕烤)。那用什么数据结构呢?
我们用一个大根堆来保存前i-1大数,大根堆确定了其中的元素是从大到小的;再用一个小根堆来存剩下的数,小根堆堆顶就是第i大数。
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
char ch=getchar();int s=0,w=1;
while(ch<48||ch>57){if(ch=='-')w=-1;ch=getchar();}
while(ch>=48&&ch<=57){s=s*10+ch-48;ch=getchar();}
return s*w;
}
inline void write(int x)
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+48);
}
int m,n;
int a[200005],b[200005];
priority_queue<int>maxx;
priority_queue<int,vector<int>,greater<int> >minn;
int main()
{
m=read(),n=read();
for(register int i=1;i<=m;i++)
{
a[i]=read();
}
for( register int i=1;i<=n;i++)
{
b[i]=read();
}
int l=1,r;
for( register int i=1;i<=n;i++)
{
r=b[i];
for(register int j=l;j<=r;j++)
{
maxx.push(a[j]);
if(maxx.size()>=i)
{
minn.push(maxx.top());
maxx.pop();
}
}
l=r+1;
cout<<minn.top()<<endl;
maxx.push(minn.top());
minn.pop();
}
return 0;
}