用树状数组维护第i个位置前面有多少空位,然后二分查询。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 50010
using namespace std;
int a[maxn];
int c[maxn];
int N;
int res[maxn];
int lowbit(int n){
return n&(-n);
}
void add(int p,int n){
while(p<=N){
c[p]+=n;
p+=lowbit(p);
}
}
int sum(int p){
int res=0;
while(p>0){
res+=c[p];
p-=lowbit(p);
}
return res;
}
int solve(int k){
int l=0,r=N+1;
int m;
while(l<r-1){
m=(l+r)>>1;
if(sum(m)>=k) r=m;
else l=m;
}
return r;
}
int main(){
while(~scanf("%d",&N)){
memset(a,0,sizeof(a));
memset(c,0,sizeof(c));
for(int i=1;i<=N;i++){
scanf("%d",&a[i]);
add(i,1);
}
for(int i=1;i<=N;i++){
res[i]=solve(a[i]);
add(res[i],-1);
}
int m;
scanf("%d",&m);
for(int i=1;i<=m;i++){
int t;
scanf("%d",&t);
printf("%d",res[t]);
if(i<m){
printf(" ");
}
else printf("\n");
}
}
return 0;
}