题目:
火车站有n个人排队,他们是按顺序到达的,但是他们乱插队。每个人有两个值pos[i]和val[i]。比如现在第5个人来了,他的pos[5]值为3,那么他就会插队到当前第3个人位置的后面(第0个人是售票窗口)。依次给出所有人的pos和val值,要你最终按所有人的位置顺序输出val值。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 200000;
struct node
{
int p;
int v;
}nodes[MAXN];
int val[MAXN*4];
int sum[MAXN*4];
int cnt,n;
#define lson i*2,l,m
#define rson i*2+1,m+1,r
void PushUp(int i)
{
sum[i]=sum[i*2]+sum[i*2+1];
}
void build(int i,int l,int r)
{
if(l==r)
{
sum[i]=1;
return ;
}
int m =(r+l)/2;
build(lson);
build(rson);
PushUp(i);
}
void print(int i,int l,int r)//输出最后一排单叶节点的值(就是val[i]的值)
{
if(l==r)
{
cnt++;
printf("%d",val[i]);
if(cnt<n)
printf(" ");
else
printf("\n");
return ;
}
int m =(r+l)/2;
print(lson);
print(rson);
}
void update(int p,int v,int i,int l,int r)//更新,直到所有节点的sum都等于0,给最下面的单叶节点重新赋值也就是排完之后的顺序。
{
if(l==r)
{
if(sum[i]==1)
{
sum[i]=0;
val[i]=v;
}
return ;
}
int m=(l+r)/2;
if(p<=sum[i*2])update(p,v,lson);
else update(p-sum[i*2],v,rson);
PushUp(i);
}
int main()
{
while(scanf("%d",&n)==1&&n)
{
cnt=0;
build(1,1,n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&nodes[i].p,&nodes[i].v);
nodes[i].p++;
}
for(int i=n;i>=1;i--)
{
int p=nodes[i].p;
int v=nodes[i].v;
update(p,v,1,1,n);
}
print(1,1,n);
}
return 0;
}