最后的人的位置一定是固定的,所以倒序插入,插入之后这个位置就不参与计数了,所以问题变成,找到第 i 个空位,线段树记录该区间里有几个空位。
#include <stdio.h> #define maxn 200010 int sum[4*maxn]; int pos[maxn],val[maxn]; int ans[maxn]; void pushup(int o) { sum[o]=sum[o*2]+sum[o*2+1]; } void build(int l,int r,int o) { if(l==r) { sum[o]=1; return; } else { int m=(l+r)/2; build(l,m,o*2); build(m+1,r,o*2+1); pushup(o); } } int query(int p,int l,int r,int o) { if(l==r) { sum[o]=0; return l; } else { int m=(l+r)/2,rank; if(sum[o*2]>p) rank=query(p,l,m,o*2); else rank=query(p-sum[o*2],m+1,r,o*2+1); pushup(o); return rank; } } int main() { int n; int i; while(scanf("%d",&n)!=EOF) { for(i=1;i<=n;i++) scanf("%d%d",&pos[i],&val[i]); build(0,n-1,1); for(i=n;i>0;i--) { int x=query(pos[i],0,n-1,1); ans[x]=val[i]; //printf("%d %d ",x,val[i]); } printf("%d",ans[0]); for(i=1;i<n;i++) printf(" %d",ans[i]); printf(" "); } return 0; }