http://poj.org/problem?id=2828
这个题,逆向思维,如果从后向前看,最后的一个人排名第几就是第几个了,然后把该位置标记为0,表示该位置已经被占,用线段树实现单点更新
#include <iostream>
#include <cstdio>
using namespace std;
#define dcout if(0) cout
#define BUG puts("here!!!");
#define STOP system("PAUSE");
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
template<class T> inline T gcd(T a,T b)//NOTES:gcd(
{if(a<0)return gcd(-a,b);if(b<0)return gcd(a,-b);return (b==0)?a:gcd(b,a%b);}
const int maxn=222222;
int sum[maxn*4];
void make(int l,int r,int rt)
{
sum[rt]=r-l+1;
if(l==r) return;
int m=(l+r)>>1;
make(lson);
make(rson);
}
int update(int x,int l,int r,int rt)
{
if(l==r) { sum[rt]=0;return l;}
int m=(l+r)>>1,ret;
if(x<=sum[rt<<1]) ret=update(x,lson);
else ret=update(x-sum[rt<<1],rson);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
return ret;
}
int ans[maxn],pos[maxn],val[maxn];
int main()
{
int n,cas=1,v,p;
while(scanf("%d",&n)==1)
{
make(1,n,1);
/*for(int i=1;i<8;i++)
dcout<<sum[i]<<" ";
dcout<<endl;*/
for(int i=1;i<=n;i++)
scanf("%d%d",&pos[i],&val[i]);
for(int i=n;i>=1;i--)
{
//scanf("%d %d",&p,&v);
/* for(int i=1;i<8;i++)
dcout<<sum[i]<<" ";
dcout<<endl;*/
ans[update(pos[i]+1,1,n,1)]=val[i];
}
for(int i=1;i<=n;i++)
{
if(i!=1) printf(" ");
printf("%d",ans[i]);
}
printf("\n");
}
return 0;
}
/*
4
0 77
1 51
1 33
2 69
4
0 20523
1 19243
1 3890
0 31492
*/