#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),

 

posted on 2012-10-18 23:25  lishimin_come  阅读(123)  评论(0编辑  收藏  举报