[关闭]
@Chilling 2017-02-16T17:57:29.000000Z 字数 1926 阅读 1234

POJ-2182: Lost Cows(树状数组+二分)

树状数组


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

Sample Input

5
1
2
1
0

Sample Output

2
4
5
3
1

题意:给出的数字表示从第2到第n只牛左边有几个比它序号小的牛,要求每个位置的牛的编号是多少。

分析:从后往前推,假如排在最后的一头牛比他编号小的数量为a,那么它的编号必然为a+1。我们把编号为a+1的这头牛删掉,假如排在倒数第二的一头牛比他编号小的数量为b,那么该牛就为删掉编号后剩余牛中的第b+1头牛。


  1. #include<stdio.h>
  2. #include<string.h>
  3. int a[8005],n,s[8005],ans[8005];
  4. int lowbit(int x)
  5. {
  6. return x&(-x);
  7. }
  8. void change(int x,int y)
  9. {
  10. for(int i=x;i<=n;i+=lowbit(i))
  11. a[i]+=y;
  12. }
  13. int sum(int x)
  14. {
  15. int sum=0;
  16. for(int i=x;i>0;i-=lowbit(i))
  17. sum+=a[i];
  18. return sum;
  19. }
  20. int sch(int l,int r,int n) //找第n个没有用过的数
  21. {
  22. int mid;
  23. while(l<=r)
  24. {
  25. mid=(l+r)/2;
  26. if(mid-(sum(mid))<n)
  27. l=mid+1;
  28. else
  29. r=mid-1;
  30. }
  31. return l;
  32. }
  33. int main()
  34. {
  35. int i,x;
  36. while(scanf("%d",&n)!=EOF)
  37. {
  38. memset(a,0,sizeof(a)); //保存个数
  39. memset(s,0,sizeof(s)); //保存输入的数据
  40. for(i=2;i<=n;i++)
  41. scanf("%d",&s[i]);
  42. for(i=n;i>0;i--)
  43. {
  44. ans[i]=sch(1,n,s[i]+1);
  45. change(ans[i],1); //标记该数字已经用过了!
  46. }
  47. for(i=1;i<=n;i++)
  48. printf("%d\n",ans[i]);
  49. }
  50. return 0;
  51. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注