Description
N (2 <= N <= 8,000) cows have unique brands in the range 1..N. In a spectacular display of poor judg
ment, they visited the neighborhood 'watering hole' and drank a few too many beers before dinner. Wh
en it was time to line up for their evening meal, they did not line up in the required ascending num
erical 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 s
illy 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 c
ows.
1~n,乱序排列,告诉每个位置的前面的数字中比它小的数的个数,求每个位置的数字是多少
ment, they visited the neighborhood 'watering hole' and drank a few too many beers before dinner. Wh
en it was time to line up for their evening meal, they did not line up in the required ascending num
erical 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 s
illy 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 c
ows.
1~n,乱序排列,告诉每个位置的前面的数字中比它小的数的个数,求每个位置的数字是多少
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 i
n slot #2; line 3 describes the number of preceding cows whose brands are smaller than the cow in sl
ot #3; and so on.
* 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 i
n slot #2; line 3 describes the number of preceding cows whose brands are smaller than the cow in sl
ot #3; and so on.
Output
* Lines 1..N: Each of the N lines of output tells the brand of a cow in line. Line #1 of the output
tells the brand of the first cow in line; line 2 tells the brand of the second cow; and so on.
tells the brand of the first cow in line; line 2 tells the brand of the second cow; and so on.
Sample Input
5
1
2
1
0
Sample Output
2
4
5
3
1
解题思路:
这个题目意思很明了(因为只有一句话)。。。
看到这个题我们会有这样的一个思路(用样例举个例子,其中a[i]为读入的它前面有几个比它小的数):
首先我们从后往前确定各个位置上的值(自己好好领会一下,大概意思就是如果从前往后,前面的值可能还要被修改一次);
step 1:因为在剩下的未填入的数字:1 2 3 4 5中1是最小的
因此:
step 2 :
因为在剩下的未填入的数字:2 3 4 5中3是第二小的
因此:
step 3:...
step 4 : ...
step 5 : ...
最后就可以得出样例了。。。
这样看来我们似乎可以用线段树单点操作来解决。。
接着就是代码了(附有较详细注释):
code:
#include<bits/stdc++.h>
using namespace std;
const int maxn=8000;
int n;
int a[maxn],tree[4*maxn+10];//tree数组里存的是剩下的数
//在这里我偷了一个懒,a数组先是读入的值,后来也被用来存答案
int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void build(int k,int l,int r)
{
if(l==r){tree[k]=1;return ;}//当走到最末尾的叶子节点的时候,它只有自己一个节点,所以是1
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
tree[k]=tree[k<<1]+tree[k<<1|1];
}
void find(int k,int l,int r,int wz)
{
if(!tree[k])return ;//没有点了当然就退出
tree[k]--;//因为要从这一段中取走一个数,自然要-1
if(l==r){a[wz]=l;return ;}//保存答案
int mid=(l+r)>>1;
if(tree[k<<1]>a[wz])find(k<<1,l,mid,wz);//如果当前要取的第a[wz]小的数比左儿子小,自然是访问左儿子
else//否则访问右儿子
{
a[wz]-=tree[k<<1];//将左儿子的数的个数减去
//因为我要接着访问右儿子,当然要将左儿子的个数减去
//实在不理解的话自己手推2遍find函数
find(k<<1|1,mid+1,r,wz);
}
tree[k]=tree[k<<1]+tree[k<<1|1];
}
int main()//主函数就不讲了。。。
{
n=read();
build(1,1,n);
for(int i=2;i<=n;i++)
a[i]=read();
for(int i=n;i>=1;i--)
find(1,1,n,i);
for(int i=1;i<=n;i++)
printf("%d\n",a[i]);
return 0;
}