【树状数组--思维】poj 2182 Lost Cows

来源:互联网 发布:c 软件外包兼职 编辑:程序博客网 时间:2024/05/21 06:26

Lost Cows
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 11826 Accepted: 7609

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

51210

Sample Output

24531

Source

USACO 2003 U S Open Orange

[Submit]   [Go Back]   [Status]   [Discuss]


题意:有n头牛牛,知道了每只牛牛的左边有多少个比他编号小的牛牛存在数组A中,问每只牛牛的编号;

思路:逆向思维,从后往前遍历A,可以很清楚的知道最后A[n]对应的编号,然后把最后一个删去,求A[n-1]对应的编号,但是刚才已经确定的编号是对之后需确定的是有影响的;

例如:0(手动补上第一个的值)  1  2  1  0  确定最后一个肯定是1;

所以还剩下 2 3 4 5 这些编号,然后确定倒数第二个,对应的编号应该是3;因为1已经被确定了;

方法就是用树状数组记录那个编号已经被确定:k-C[k]=A[i]+1;

代码:

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;const int maxn=8005;int A[maxn],C[maxn];int n,ans[maxn];int lowbit(int k){    return k&(-k);}void add(int x,int d){    while(x<=maxn)    {        C[x]+=d;        x+=lowbit(x);    }}int sum(int x){    int ret=0;    while(x>0)    {        ret+=C[x];        x-=lowbit(x);    }    return ret;}int bi_search(int x){    int l=1,r=8000;    while(l<r)    {        int mid=(l+r)/2;//        printf("%d\n",mid);        if(mid-sum(mid)<x)            l=mid+1;        else            r=mid;    }    return l;}int main(){    scanf("%d",&n);    memset(C,0,sizeof(C));    A[1]=1;    for(int i=2; i<=n; i++)    {        scanf("%d",&A[i]);        A[i]+=1;    }    for(int i=n; i>0; i--)    {        int k=bi_search(A[i]);        add(k,1);        ans[i]=k;    }    for(int i=1; i<=n; i++)        printf("%d\n",ans[i]);    return 0;}



原创粉丝点击