POJ 2182 Lost Cows(树状数组)

来源:互联网 发布:怎么样注册淘宝店 编辑:程序博客网 时间:2024/05/18 02:39

Problem Q

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other)
Total Submission(s) : 35   Accepted Submission(s) : 23
Problem 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 <br> <br>* 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. <br>
 

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
 


树状数组。初始时,树状数组为全0.sum(x)表示已经确定了值的且小于等于x的值的个数。

我们依然从后往前倒推,对于当前考虑的a[n],假设它的值为x,那么我们就执行add(x,1)。接下来我们要找到a[n-1]的值y,y肯定在[1,8000]范围内,所以可以用二分查找确定y的值。如果我们猜y=8的话,如果a[n-1]=4并且比8小的已经确定了的值即sum(7)=3,可以说明从1到7中:由有3个数的值已经确定了 并且 还有4个值没有确定且这些没确定值的比y小的数正好是4个,那么y肯定>=8。可以加大y的范围继续探测。如果sum(7)+4<7的话,8就比y本来的值要大了。

如果sum(7)+4>7的话,8就比y本来的值要小。

       由此可得一般结论,我们猜测当前a[i]的值为y,如果

Sum(y-1)+a[i]==y-1 那么y为最小值

Sum(y-1)+a[i]<y-1 那么y-1为最大值

Sum(y-1)+a[i]>y-1 那么y+1为最小值

 

AC代码:0ms 注意if else语句的顺序,发生概率大的语句放前面。

代码:

#include<cstdio>#include<cstring>#include<iostream> #include<algorithm>using namespace std;const int MAXN =8008;int a[MAXN];int ans[MAXN];int c[MAXN];int n;int lowbit(int x){    return x&(-x);}int sum(int x){    int res=0;    while(x)    {        res +=c[x];        x-=lowbit(x);    }    return res;}void add(int x,int v){    while(x<=n)    {        c[x]+=v;        x+=lowbit(x);    }}int main(){ios::sync_with_stdio(false);    while(cin>>n&&n)    {        a[1]=0;        memset(c,0,sizeof(c));        for(int i=2;i<=n;i++)        cin>>a[i];        ans[n] = a[n]+1;        add(a[n] + 1 , 1);        for(int i=n-1;i>=1;i--)        {            int L=1,R=n;            while(R>L)            {                int mid = (R+L+1)/2;                if(sum(mid-1)+a[i] < mid-1)                    R=mid-1;                else if(sum(mid-1)+a[i] == mid-1)                    L=mid;                else                    L=mid+1;            }            ans[i]= L ;            add(ans[i] , 1 );        }        for(int i=1;i<=n;i++)            cout<<ans[i]<<endl;    }    return 0;}


原创粉丝点击