初看这道题似乎是一道平衡树的水题, 每次加入队列时查找平衡树上对应的点并插入新的节点, 然而仔细思考后可以发现可以运用线段树完成此题。
我们可以发现, 从后往前处理时, 前面为第Pos个人即意味着当前人前方有Pos个人, 所以我们可以用线段树维护剩下的空位个数, 将信息离线下来进行处理。
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
#define R register
#define IN inline
#define W while
#define gc getchar()
#define ls now << 1
#define rs now << 1 | 1
struct Node
{
int lef, rig, sum;
}tree[2000005];
int result[200005];
struct Command
{
int pos, val;
}command[200005];
IN void pushup(const int &now)
{
tree[now].sum = tree[ls].sum + tree[rs].sum;
}
void build (int now, int lef, int rig)
{
tree[now].lef = lef, tree[now].rig = rig;
if(lef == rig)
{
tree[now].sum = 1;
return;
}
int mid = (lef + rig) >> 1;
build(ls, lef, mid);
build(rs, mid + 1, rig);
pushup(now);
}
int get_pos(const int &now, const int &need)
{
if(tree[now].sum == need && tree[now].lef == tree[now].rig)
{
tree[now].sum = 0;
return tree[now].lef;
}
if(tree[ls].sum >= need)
{
int ans = get_pos(ls, need);
pushup(now);
return ans;
}
else
{
int ans = get_pos(rs, need - tree[ls].sum);
pushup(now);
return ans;
}
}
int main()
{
int num;
scanf("%d", &num);
for (R int i = 1; i <= num; ++i)
{
scanf("%d%d", &command[i].pos, &command[i].val);
}
build(1, 1, num);
for (R int i = num; i >= 1; --i)
{
result[get_pos(1, command[i].pos + 1)] = command[i].val;
}
for (R int i = 1; i <= num; ++i)
printf("%d ", result[i]);
return 0;
}