本题关键在于知道从后往前找的话,前面有n个点,就是指,该点为第n+1个未使用的点,我们用树状数组的add来确定某点是否被使用,一旦使用就add(x,-1)把他减去,用sum求某点是第几个未被使用的点,之后用二分法确定哪个点是未被使用的第n+1个点,把那点的数值赋给ans,最后按序输出即可。
#include <stdio.h>
int h[10000];
int ans[10000];
int c[10000];
int n;
int lowbit(int k)
{
return (k&(-k));
}
int sum(int x) //求和
{
int ret = 0;
while(x>0)
{
ret+=c[x];
x-=lowbit(x);
}
return ret;
}
void add(int x,int d) //修改节点的值
{
while(x<=n)
{
c[x]+=d;
x+=lowbit(x);
}
}
int main()
{
int i,j;
scanf("%d",&n);
for(i=2;i<=n;i++)
{
scanf("%d",&h[i]);
}
h[1]=0;
for(i=1;i<=n;i++)
{
add(i,1);
}
for(i=n;i>=1;i--)
{
int l=1,r=n;
int fou=h[i]+1;
while(l<=r)
{
int mid=(l+r)/2;
if(sum(mid)<fou)
l=mid+1;
else
r=mid-1;
}
ans[i]=l;
add(l,-1);
}
for(i=1;i<=n;i++)
printf("%d\n",ans[i]);
return 0;
}