题目大意:要你模拟一个黑匣子的两种操作:①插入一个数;②给i+1,并输出当前黑匣子中第i小的数。初始i为0。
解题思路:离散化+权值线段树。先把插入的数离散成1~200000里的数,再放进权值线段树里,顺便进行询问。
C++ Code:
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; int n,m; int a[200005],b[200005],d[1000005]; void add(int l,int r,int cur,int k){ if(l==r){ ++d[cur]; return; } int mid=l+r>>1; if(k<=mid)add(l,mid,cur<<1,k);else add(mid+1,r,cur<<1|1,k); d[cur]=d[cur<<1]+d[cur<<1|1]; } int query(int l,int r,int cur,int k){ if(l==r)return l; int mid=l+r>>1; if(k<=d[cur<<1])return query(l,mid,cur<<1,k);else return query(mid+1,r,cur<<1|1,k-d[cur<<1]); } int main(){ scanf("%d%d",&m,&n); for(int i=1;i<=m;++i)scanf("%d",&a[i]); memcpy(b,a,sizeof(b)); sort(b+1,b+m+1); int N=unique(b+1,b+m+1)-b-1; int now=0,I=0; for(int i=1;i<=n;++i){ int f; scanf("%d",&f); for(int j=now+1;j<=f;++j)add(1,200000,1,lower_bound(b+1,b+N+1,a[j])-b); now=f; printf("%d ",b[query(1,200000,1,++I)]); } }