题目:http://poj.org/problem?id=2828
题意:
排队买票,有插队的,输出最终的队伍序列。
思路:
总共就有n个位置。
因为最后一个选定位置后就自身位置就确定了,依次向前,所以倒序遍历,线段树中储存的是当前位置向前还有多少个位置。
#include <stdio.h>
#include <iostream>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int maxn = 200004;
int pos[maxn];
int val[maxn];
int tree[maxn<<2];
void PushUp(int rt){
tree[rt] = tree[rt<<1]+tree[rt<<1|1];
}
void build(int l,int r,int rt){
tree[rt] = r - l + 1;
if(l == r){
return;
}
int m = (l+r)>>1;
build(lson);
build(rson);
}
int id;
void update(int p,int l,int r,int rt){
if(l == r){
id = l;
tree[rt]=0;
return;
}
int m = (l+r)>>1;
if(tree[rt<<1] >= p)
update(p,lson);
else{
p -= tree[rt<<1];
update(p,rson);
}
PushUp(rt);
}
int main(){
int n;
while(~scanf("%d",&n)){
for(int i = 1;i <= n;i++)
scanf("%d%d",pos+i,val+i);
int ans[maxn];
build(1, n, 1);
for(int i = n;i > 0;i--){
update(pos[i]+1, 1, n, 1);
ans[id] = val[i];
}
// for(int i = 1;i < n*4;i++)
// printf("%d ",tree[i]);
printf("%d",ans[1]);
for(int i = 2;i <= n;i++)
printf(" %d",ans[i]);
printf("\n");
}
return 0;
}