此题的关键在于逆序更新,并且要将pos位置转化为后面的点还未插入时应当剩余的空位置
//最后一个插入到该位置的人的位置是固定的,从后面进行插入操作,pos代表要插入到pos位置
//则在前面插入pos时pos前面要留出pos个空位置,去掉后来插入的点
#include<cstdio>
#include<iostream>
using namespace std;
const int maxn=200002;
int tree[maxn<<2],ans[maxn<<2];
struct node{
int pos,val;
}s[maxn];
void Pushup(int p)
{
tree[p]=tree[p<<1]+tree[p<<1|1]; //维护区间空位置的个数
}
void Build(int p,int l,int r)
{
if(l==r)
{
tree[p]=1;
return;
}
int mid=(l+r)/2;
Build(p<<1,l,mid);
Build(p<<1|1,mid+1,r);
Pushup(p);
}
void Update(int p,int l,int r,int pos,int val) //单点更新
{
if(l==r)
{
tree[p]=0;
ans[l]=val;
return;
}
int mid=(l+r)/2;
if(tree[p<<1]>=pos) Update(p<<1,l,mid,pos,val);
else{
Update(p<<1|1,mid+1,r,pos-tree[p<<1],val);
}
Pushup(p); //漏写致错
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%d%d",&s[i].pos,&s[i].val);
}
Build(1,1,n);
for(int i=n-1;i>=0;i--)
{
Update(1,1,n,s[i].pos+1,s[i].val);
}
for(int i=1;i<=n;i++)
cout<<ans[i]<<' ';
cout<<endl;
}
return 0;
}