题目:http://poj.org/problem?id=2828
题意是n个人按照给定的位置(pos),将这些人插入到这个位置。按它正常的顺序去模拟的话肯定会超时(n^2).所以这题用的是逆着来统计。。用线段树统计T[1-n]的空位置数量。由于逆着进行统计。只需要找到把当前这个人的实际位置找出来,而这个实际的位置与给定的这个人的pos有关。如果pos是空的。那么这个人的实际位置就是放在pos这个点上。(前面的人不能改变后面人的位置)。而如果pos这个点有人(说明是后面有人已经占领了这个位置)。那么实际位置肯定会大于pos这个点。
下面是AC代码:
#include<cstdio> using namespace std; #define maxn 200010 int T[maxn<<2]; int pos[maxn],val[maxn],ans[maxn]; int index; void build(int id,int l,int r){ T[id] = r-l+1; if(l==r) return ; int mid=(l+r)>>1; build(id<<1,l,mid); build((id<<1)+1,mid+1,r); } void update(int id,int l,int r,int pos){ T[id]--; if(l==r){ index = l; return; } int m = (l+r)>>1; if(T[id<<1]>=pos) update(id<<1,l,m,pos); else { pos-=T[id<<1];update((id<<1)+1,m+1,r,pos); } } int main(){ int n; while(scanf("%d",&n)!=EOF){ build(1,1,n); for(int i=1;i<=n;i++) scanf("%d%d",&pos[i],&val[i]); for(int i=n;i>=1;i--){ update(1,1,n,pos[i]+1); ans[index]=val[i]; } for(int i=1;i<=n;i++) printf(i==n?"%d\n":"%d ",ans[i]); } return 0; }