易错点:
- 每头牛对应一个身高,且所有身高在范围[1~n]内.(预处理时需要在树状数组中提前加入每个身高)
- 每头牛所属的位置是它前面牛数量+1,例如:小A分数比小B分数大的数值为无穷小,那么小B的名次就是小A的后一名。因此,在查询位次(即身高)时需要使用query(a[i]+1).
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int MAXN=2e5;
int a[MAXN],n;
int lowbit(int x){
return x&-x;
}
int tr[MAXN];
void add(int x,int val){
while(x<=n){
tr[x]+=val;
x+=lowbit(x);
}
}
int ask(int x){
int ans=0;
while(x){
ans+=tr[x];
x-=lowbit(x);
}
return ans;
}
int query(int x){
int l=1,r=n;
while(l<r){
int mid=(l+r)>>1;
if(ask(mid)<x)l=mid+1;
else r=mid;
}
return l;
}
int h[MAXN];
int main(){
scanf("%d",&n);
for(int i=2;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++)
add(i,1);//
for(int i=n;i>=1;i--){
h[i]=query(a[i]+1);//
add(h[i],-1);
}
for(int i=1;i<=n;i++)
printf("%d
",h[i]);
return 0;
}