谜一样的牛
有n头奶牛,已知它们的身高为 1~n 且各不相同,但不知道每头奶牛的具体身高。
现在这n头奶牛站成一列,已知第i头牛前面有Ai头牛比它低,求每头奶牛的身高。
输入格式
第1行:输入整数n。
第2…n行:每行输入一个整数Ai,第i行表示第i头牛前面有Ai头牛比它低。
(注意:因为第1头牛前面没有牛,所以并没有将它列出)
输出格式
输出包含n行,每行输出一个整数表示牛的身高。
第i行输出第i头牛的身高。
数据范围
1≤n≤105
输入样例:
5
1
2
1
0
输出样例:
2
4
5
3
1
#include<iostream>
using namespace std;
const int N=110;
//h[i]表示第i头牛的身高
int tree[N],h[N],a[N];
int n;
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int v)
{
while(x<=n)
{
tree[x]+=v;
x+=lowbit(x);
}
}
int sum(int x)
{
int res=0;
while(x)
{
res+=tree[x];
x-=lowbit(x);
}
return res;
}
int main()
{
ios::sync_with_stdio(false);//优化cin
cin>>n;
add(1,1);
for(int i=2;i<=n;i++)
{
cin>>a[i];
//将tree[i]全部初始化为1
add(i,1);
}
//从后往前依次确定牛的身高
for(int i=n;i>=1;i--)
{
int c=1,b=n;
while(c<b)
{
int mid=(c+b)>>1;
//第i头牛前面有a[i]头比它矮,那么它在它之前的牛里面是第a[i]+1高的
//利用树状数组求前缀和,初始时sum(i)=i;
if(sum(mid)<a[i]+1)
c=mid+1;
else
b=mid;
}
h[i]=b;//第i头牛的高为b
add(b,-1);//tree[b]=0
}
for(int i=1;i<=n;i++)
cout<<h[i]<<endl;
return 0;
}