线段树
区间存储空位数
逆序插入即可
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int n;
int pos[200001],val[200001],newpos[200001];
struct point{
int l,r;
int num;
}tree[600000];
void build(int s,int t,int id){
tree[id].l=s;
tree[id].r=t;
tree[id].num=t-s+1;
if(s!=t){
int mid=(s+t)>>1;
build(s,mid,id<<1);
build(mid+1,t,(id<<1)+1);
}
}
/*void update(int s,int id){
if(tree[id].l==tree[id].r){
tree[id].num=0;
return;
}
int mid=(tree[id].l+tree[id].r)>>1;
if(mid>=s)
update(s,id*2);
else
update(s,id*2+1);
tree[id].num=tree[id*2].num+tree[id*2+1].num;
}*/
int query(int id,int tem){
tree[id].num--;
if(tree[id].l==tree[id].r)
return tree[id].l;
int mid=(tree[id].l+tree[id].r)>>1;
if(tree[(id<<1)].num>=tem)
return query((id<<1),tem);
return query((id<<1)+1,tem-tree[(id<<1)].num);
}
int main(){
int i,j;
while(scanf("%d",&n)==1){
for(i=1;i<=n;i++)
scanf("%d %d",&pos[i],&val[i]);
build(1,n,1);
for(i=n;i>=1;i--){
int s=query(1,pos[i]+1);
newpos[s]=val[i];
//update(s,1);
}
for(i=1;i<n;i++)
printf("%d ",newpos[i]);
printf("%d\n",newpos[n]);
/*for(i=1;i<=n;i++){
printf("%d",newpos[i]);
if(i!=n)
printf(" ");
}
printf("\n");*/ //这几处导致G++ TLE
}
}