一个很好的线段树应用的题! 题意:有一些人去买票,但是后来的可以插队,插到自己想插的pos。 思路:反过来看,pos就变成了前面有多少个空位,这样就可以用线段树了 /* * File: main.cpp * Author: Mi * * Created on 2011年3月30日, 上午9:47 */ #include <cstdlib> #include <stdio.h> #include <algorithm> #define N 200005 using namespace std; /* * */ struct tree { int l,r,len;//记录有多少个空位 int mid() { return (l+r)>>1; } }T[N*4]; struct node { int pos,value; }p[N]; int ans[N]; void build(int l,int r,int root) { T[root].l=l,T[root].r=r; T[root].len=r-l+1; if(l==r) return ; int mid=T[root].mid(); build(l,mid,root<<1); build(mid+1,r,root<<1|1); } int query(int pos,int root) { T[root].len--;//插入一个人空位就减少一个 if(T[root].l==T[root].r) return T[root].l;//找到位置 if(T[root<<1].len>=pos)//先看能不能插在左边,也就是前面 return query(pos,root<<1); else { pos-=T[root<<1].len;//如果前面不能插,那么前面已经有了T[root].len个空位了,就还需要pos-T[root].len个空位 return query(pos,root<<1|1); } } int main(int argc, char** argv) { int n; while(scanf("%d",&n)==1) { build(1,n,1); for(int i=1;i<=n;i++) scanf("%d%d",&p[i].pos,&p[i].value); for(int i=n;i>=1;i--) ans[query(p[i].pos+1,1)]=p[i].value; for(int i=1;i<=n;i++) printf("%d%c",ans[i],i==n?'/n':' '); } return 0; }