如果最后一头奶牛前面有 AnA_n 头牛比它高,那么显然他的身高 Hn=An+1H_n=A_n+1

如果倒数第二头前面有 An1A_{n-1} 头牛比它高,那么:

1.如果 An1<AnA_{n-1}<A_n,那么它的身高为 Hn1=An1+1H_{n-1}=A_{n-1}+1

2.如果 An1AnA_{n-1}\geqslant A_n,那么它的身高为 Hn1=An1+2H_{n-1}=A_{n-1}+2.

依此类推,如果第 kk 头牛前面有 AkA_k 头比它高,那么它的身高 HkH_k 是数值 1n1\thicksim n 中第 Ak+1A_k+1 小的没有在 Hk+1,Hk+2,Hn{H_{k+1},H_{k+2},…H_n} 中出现过的数。

具体来说,我们建立一个长度为 nn0101 序列 bb,起初全部为 11,然后从 nn11 倒序扫描每个 AiA_i,对每个 AiA_i 执行两个操作。

1.查询序列 bb 中第 Ai+1A_{i+1}11 在什么位置,这个位置号就是第 ii 头奶牛的身高 HiH_i

2.把 b[Hi]b[H_i]11 变为 00.

然后我们如果想查询身高,就直接对 bb 数组进行下标查询操作即可。

#include<stdio.h>
int n,a[8010],tree[8010];
int vis[8010],ans[8010];
int lowbit(int x)
{
    return x&(-x);
}
void update(int x,int val)
{
    for(int i=x;i<=n;i+=lowbit(i))
        tree[i]+=val;
}
int ask(int x)
{
    int ans=0;
    for(int i=x;i;i-=lowbit(i))
        ans+=tree[i];
    return ans;
}
int two_devide(int x)
{
    int l=1,r=n;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(ask(mid)<x)
            l=mid+1;
        else
            r=mid-1;
    }
    return l;
}
int main()
{
    scanf("%d",&n);
    for(int i=2;i<=n;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
        update(i,1);
    for(int i=n;i>=2;i--)
    {
        ans[i]=two_devide(a[i]+1);
        vis[ans[i]]=1;
        update(ans[i],-1);
    }
    for(int i=1;i<=n;i++)
        if(!vis[i])
        {
            printf("%d\n",i);
            break;
        }
    for(int i=2;i<=n;i++)
        printf("%d\n",ans[i]);
    return 0;
}