//思路:从最后一个人往前插,这样pos的意义就变成了,前面有多少个空位。
//线段树上每个节点中存储的是当前时刻,该区间有多少空位。
//如果某个人插入到pos[i],则找第pos[i]个空位置插入即可
#include <iostream>
using namespace std;
struct node{
int from, to;
int cap;
};
const int MAX_NUM = 200002;
node line[3*MAX_NUM];
int pos[MAX_NUM], val[MAX_NUM], ans[MAX_NUM];
int n;
//建树
void build_tree(int left, int right, int c)
{
line[c].from = left;
line[c].to = right;
line[c].cap = right - left + 1;
if (left == right) return;
int mid = (left + right) / 2;
build_tree(left, mid, c<<1);
build_tree(mid+1, right, (c<<1)+1);
}
int insert(int pos)
{
int c = 1;
while (line[c].from != line[c].to){
line[c].cap--; //当前节点容量减1
//如果左半边容量足够大,则递归进入左半边
if (line[c<<1].cap >= pos){
c <<= 1;
}
else{
pos -= line[c<<1].cap;
c = ((c<<1)+1);
}
}
//递归结束,找到插入的位置
line[c].cap--;
return line[c].from;
}
int main()
{
int i;
while (scanf("%d", &n) != EOF){
build_tree(1, n, 1);
for (i = 0; i < n; ++i)
scanf("%d%d", &pos[i], &val[i]);
for (i = n-1; i >= 0; --i)
ans[insert(pos[i]+1)] = val[i];
for (i = 1; i < n; ++i)
printf("%d ", ans[i]);
printf("%d\n", ans[i]);
}
return 0;
}
poj 2828 (线段树)
最新推荐文章于 2019-05-29 19:25:37 发布