题目链接

http://poj.org/problem?id=2182
题目大意说起来挺麻烦的,不说了。

唯一一个能看懂的题解

https://www.cnblogs.com/wzj-xhjbk/p/9737282.html
我就直接讲代码了

AC代码

#include<iostream>
#define ll long long
#define x first
#define y second
const int inf=0x3f3f3f3f;
using namespace std;
const int N=1e4;
int c[N],a[N],ans[N],n;
inline int lowbit(int x)
{
    return x&(-x);
}
int getsum(int x)
{
    int sum=0;
    while(x)
    {
        sum+=c[x];
        x-=lowbit(x);
    }
    return sum;
}
void update(int x,int add)
{
    while(x<=n)
    {
        c[x]+=add;
        x+=lowbit(x);
    }
}
int main()
{
    cin>>n;
    a[1]=0;
    for(int i=2;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=n;i>=1;i--)
    {
        int l=0,r=n,pos;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(mid>=a[i]+getsum(mid)+1) //mid是我们假设插入的位置,a[i]为比当前我们处理的这头牛编号小且在该牛前面的牛的数量(说白了就是题目让输入的!);getsum(mid)求得的是在当前我们处理的这头牛之前,已经插入在mid位置之前的牛有几头(这些已经插入的牛的编号都比当前牛的大)//我写的好长,你自己复制下来调整一下长度看吧,我懒得改了。
            r=mid-1,pos=mid;
            else l=mid+1;
        }
        update(pos,1);//二分得到的插入位置,进行标记(比较抽象,需要好好理解)
        ans[i]=pos;//编号为i的牛的位置。
    }
    for(int i=1;i<=n;i++)
    cout<<ans[i]<<endl;
}