1. 程式人生 > >Lost Cows poj2182

Lost Cows poj2182

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;
}