n头奶牛,身高为1—n,已知第i头奶牛前有ai头奶牛比他低,求每头牛的身高。
题解:若最后一头牛前有a头比他低,则他的身高为a+1.
倒数第二头前有a头比他低,则:1,倒数第二头比最后一头低,则身高为a+1。2,倒数第二头比最后一头高,则身高为a+2。以此类推。
若第k头奶牛前有a头比他低,则他的身高就是1--n中第a+1小的没有在他身后出现过的身高。
建立一个长度为n的01序列,初始全为1,求第k大。
#include<iostream>
#include<cstring>
#define f(i,l,r) for(i=(l);i<=(r);i++)
#define ff(i,r,l) for(i=(r);i>=(l);i--)
using namespace std;
const int MAXN=8005;
int n,tree[MAXN],a[MAXN];
inline int Lowbit(int x)
{
return x&(-x);
}
inline int query(int x)
{
int res=0,i;
for(i=x;i;i-=Lowbit(i)){
res+=tree[i];
}
return res;
}
inline void add(int x,int d)
{
int i;
for(i=x;i<=n;i+=Lowbit(i)){
tree[i]+=d;
}
}
inline int Kth(int k)
{
int i;
int ans=0,sum=0;
ff(i,12,0){
ans+=(1<<i);
if(ans>=n||sum+tree[ans]>=k) ans-=(1<<i);
else sum+=tree[ans];
}
return ans+1;
}
int main()
{
ios::sync_with_stdio(false);
int i,j;
cin>>n;
f(i,2,n){
cin>>a[i];
}
f(i,1,n){
add(i,1);
}
ff(i,n,1){
a[i]=Kth(a[i]+1);
add(a[i],-1);
}
f(i,1,n) cout<<a[i]<<endl;
return 0;
}