@Chilling
2017-02-16T17:57:29.000000Z
字数 1926
阅读 1234
树状数组
Description
N (2 <= N <= 8,000) cows have unique brands in the range 1..N. In a spectacular display of poor judgment, they visited the neighborhood 'watering hole' and drank a few too many beers before dinner. When it was time to line up for their evening meal, they did not line up in the required ascending numerical order of their brands.
Regrettably, FJ does not have a way to sort them. Furthermore, he's not very good at observing problems. Instead of writing down each cow's brand, he determined a rather silly statistic: For each cow in line, he knows the number of cows that precede that cow in line that do, in fact, have smaller brands than that cow.
Given this data, tell FJ the exact ordering of the cows.
Input
Line 1: A single integer, N
Lines 2..N: These N-1 lines describe the number of cows that precede a given cow in line and have brands smaller than that cow. Of course, no cows precede the first cow in line, so she is not listed. Line 2 of the input describes the number of preceding cows whose brands are smaller than the cow in slot #2; line 3 describes the number of preceding cows whose brands are smaller than the cow in slot #3; and so on.
Output
Sample Input
5
1
2
1
0
Sample Output
2
4
5
3
1
题意:给出的数字表示从第2到第n只牛左边有几个比它序号小的牛,要求每个位置的牛的编号是多少。
分析:从后往前推,假如排在最后的一头牛比他编号小的数量为a,那么它的编号必然为a+1。我们把编号为a+1的这头牛删掉,假如排在倒数第二的一头牛比他编号小的数量为b,那么该牛就为删掉编号后剩余牛中的第b+1头牛。
#include<stdio.h>
#include<string.h>
int a[8005],n,s[8005],ans[8005];
int lowbit(int x)
{
return x&(-x);
}
void change(int x,int y)
{
for(int i=x;i<=n;i+=lowbit(i))
a[i]+=y;
}
int sum(int x)
{
int sum=0;
for(int i=x;i>0;i-=lowbit(i))
sum+=a[i];
return sum;
}
int sch(int l,int r,int n) //找第n个没有用过的数
{
int mid;
while(l<=r)
{
mid=(l+r)/2;
if(mid-(sum(mid))<n)
l=mid+1;
else
r=mid-1;
}
return l;
}
int main()
{
int i,x;
while(scanf("%d",&n)!=EOF)
{
memset(a,0,sizeof(a)); //保存个数
memset(s,0,sizeof(s)); //保存输入的数据
for(i=2;i<=n;i++)
scanf("%d",&s[i]);
for(i=n;i>0;i--)
{
ans[i]=sch(1,n,s[i]+1);
change(ans[i],1); //标记该数字已经用过了!
}
for(i=1;i<=n;i++)
printf("%d\n",ans[i]);
}
return 0;
}