用大根堆和小根堆分别存放前$i-1$大的元素前$k-i$小的元素。 将当前序列的元素压入最小堆,如果最小堆的最小数大于最大堆的最大数则进行交换,保证最大堆中的所有数小于最小堆。 因为$i$值每进行一次自增$1$,所以每次$get$操作后将小根堆顶弹出存入大根堆。
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<cctype> #include<cstdlib> #include<vector> #include<queue> #include<map> #include<set> #define ull unsigned long long #define ll long long #define R register int using namespace std; namespace Fread { static char B[1<<15],*S=B,*D=B; #define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++) inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } inline bool isempty(const char& ch) {return ch<=36||ch>=127;} inline void gs(char* s) {register char ch; while(isempty(ch=getchar())); do *s++=ch; while(!isempty(ch=getchar()));} }using Fread::g; using Fread::gs; priority_queue<int> bq; priority_queue<int,vector<int>,greater<int> > sq; int a[30010]; int n,m; signed main() { #ifdef JACK freopen("NOIPAK++.in","r",stdin); #endif n=g(),m=g(); for(R i=1;i<=n;++i) a[i]=g(); R k=1; for(R i=1;i<=m;++i) { R x=g(); while(k<=x) { sq.push(a[k]); if(bq.size()&&bq.top()>sq.top()) { R tmp=bq.top(); bq.pop(); sq.push(tmp); tmp=sq.top(); sq.pop(); bq.push(tmp); } ++k; } printf("%d ",sq.top()); R tmp=sq.top(); sq.pop(); bq.push(tmp); } }
2019.06.13