题目地址:http://poj.org/problem?id=2828
/*
Author:Bob Lee
2012.9.25
==========================================================
线段树的更新
先说题意:
n个人陆续到一个队列排队,但是有的人可能会插队,题目给出第i个人插在pos[i]的位置,问最后队列的情况如何。
解题思路:
我们可以发现越往后面插的人是有一定优先权的
也就是最后一个人插入的话一定可以达到自己的目的
在这里
建立一颗线段树,来表示某一个区间内还有的空位数
然后我们从最后一个人开始插队
具体细节见代码
这题还是很经典的,应该仔细研究研究
*/
#include<iostream>
#include<cstdio>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define maxn 200005
int tree[maxn<<2];
int pos[maxn];
int value[maxn];
int ans[maxn];
int lastpos;
void build(int l,int r,int rt)
{
//初始数据就是他们之间一个人都没插
tree[rt] = r-l+1;
if(l == r)
return;
int m = (l+r)>>1;
build(lson);
build(rson);
}
void update(int p,int l,int r,int rt)
{
tree[rt]--;
if(l == r)
{
lastpos = l;
return;
}
int m = (l+r)>>1;
/*
如果左儿子的空位大于p,那么p就插到左儿子去
否则
则在右儿子这边,找一个pos = p-左儿子的空位数 的地方插
*/
if(tree[rt<<1] >= p)
update(p,lson);
else
{
p = p-tree[rt<<1];
update(p,rson);
}
}
int main()
{
int n;
while(~scanf("%d",&n))
{
build(1,n,1);
for(int i=1;i<=n;i++)
scanf("%d%d",pos+i,value+i);
for(int i=n;i>0;i--)
{
update(pos[i]+1,1,n,1);
ans[lastpos] = value[i];
}
for(int i=1;i<=n-1;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[n]);
}
return 0;
}