【[POJ2182】Lost Cows

                                                Lost Cows

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 12717   Accepted: 8157

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

* 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.

Sample Input

5
1
2
1
0

Sample Output

2
4
5
3
1

解析:

       从后往前,如果第 K 头牛前面有 Ak 头比它低,那么它的身高 Hk 是数值 1~N 中第 Ak + 1 小的没有在{Hk+1 , Hk+2,......Hn}中出现的数,具体讲就是建立一个长度为 n 的 01 序列 b,起初全部为 1 。然后从 n  到 1  倒序扫描每个 Ai ,对每个 Ai 执行以下两个操作:

       1.查询序列 b 中第 Ai + 1 个 1 在什么位置,这个位置号就是第 i 头奶牛的身高 Hi。

       2.把 b[ H[ i ] ] 减一(从1变为0)

       直接用树状数组 + 二分即可完成,当然还有倍增的做法但是不想打了。。。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int Max=10010;
int n,m,l,r,mid;
int num[Max],a[Max],h[Max];

inline int get_int()
{
	int x=0,f=1;
	char c;
	for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
	if(c=='-') {f=-1;c=getchar();(!isdigit(c))&&(c!='-');c=getchar();}
	for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
	return x*f;
}

inline int lowbit(int x){return x&-x;}
inline void add(int pos,int x){for(;pos<=n;pos+=lowbit(pos)) num[pos]+=x;}
inline int Q(int pos)
{
	int sum=0;
	for(;pos>=1;pos-=lowbit(pos)) sum+=num[pos];
	return sum;
}

int search(int x)
{
	int l=1,r=n;
	while(l<r)
	{
		int mid=(l+r)/2;
		if(Q(mid)<x) l=mid+1; else r=mid;
	}
	return l;
}

int main()
{
	n=get_int();
	for(int i=2;i<=n;i++) a[i]=get_int(),add(i,1);
	add(1,1);

	for(int i=n;i>=1;i--)
	{
	  h[i] = search(a[i]+1);
	  add(h[i],-1);
	}
	for(int i=1;i<=n;i++) cout<<h[i]<<"\n";

	return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_38083668/article/details/81460868