可以直接用平衡树暴力做,但杀鸡焉用牛刀,这里介绍二分方法。
考虑将插入序列翻转,那么翻转后的第一行可以确定其位置。那么第二行的插入,如果插入的位置在第一次插入之前,那么说明最后一次插入不会影响到这一次插入。我们直接将其插入对应位置。反之,如若在后,那么要将其向后移动一个位置。
如此反复的,对于当前插入于 $p$ 之后的操作,我们首先计算 $1$ 到 $p$ 中已经确定答案的数量 $c$,在 $p+1$ 开始的第 $c$ 个空位插入当前数即可。
可以用树状数组维护这个操作。寻找空位时用二分。总复杂度 $\mathcal O(n\log^2n)$。
```cpp
for (int i = 1; i <= n; i ++) scanf ("%d%d", pos + i, val + i);
for (int i = n; i >= 1; i --) {
int left = t.query (pos[i]);
int p = pos[i] + 1;
int l = p, r = n;
int ls = t.query (pos[i]);
while (l <= r) {
int mid = l + r >> 1;
if (t.query (mid) - ls + left <= mid - pos[i] - 1) p = mid, r = mid - 1;
else l = mid + 1;
}
t.add (p, 1);
ans[p] = val[i];
}
for (int i = 1; i <= n; i ++) printf ("%d ", ans[i]);
puts ("");
```