#include <iostream>
using namespace std;
const int maxn=8000+10;
struct node
{
int l,r,len;
}tree[maxn*3];
void Create(int p,int l,int r)
{
tree[p].l=l;
tree[p].r=r;
tree[p].len=r-l+1;
if(l!=r)
{
int mid=(l+r)/2;
Create(2*p+1,l,mid);
Create(2*p+2,mid+1,r);
}
}
int find(int p,int am)
{
tree[p].len--;
if(tree[p].l==tree[p].r)
return tree[p].l;
if(am<=tree[p*2+1].len)
return find(p*2+1,am);
else
return find(p*2+2,am-tree[p*2+1].len);
}
int main()
{
int n,a[maxn],b[maxn];
while(cin>>n)
{
int i;
Create(0,1,n);
for(i=1;i<n;i++)
cin>>a[i];
for(i=n-1;i>0;i--)
b[i]=find(0,a[i]+1);
b[0]=find(0,1);
for(i=0;i<n;i++)
cout<<b[i]<<endl;
}
return 0;
}
暴力的解题思路:在最初的排列中,可以先确定最后位置i的编号:已知a[i],b[i]=a[i]+1,因为他之前的比它小的数已经是除了他之外的所有数。然后在1·n的区间中去掉已得到的数,划区间1-1,1-2,到1-n,得到后的数,在包含它 的区间中删除,对应的区间所包含的数目-1,。然后寻找从后往前的下一个数i每个区间挨着寻找,直到这个区间中1-t所包含的数正好等于a[i]+1,可得b[i]=t,用数组可实现上述算法.
以此类推,直到剩下最后一个数。再遍历每个区间,知道1~t所包含的数恰好等于1,可得最后剩下的数的编号。时间为O(n2)。
可以用线段数优化查找区间所用的时间,时间效率可优化到O(nlgn),