题目: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;
}