(1)思路:
一开始想用链表做,但是链表无法处理第几个这个问题。
后来参考大佬的文章,发现先进入的人之前的空格数是确定的就是id+1,
所以我们可以建立线段树,找到这个点的位置,然后更新这个点。
(2)注意:更新时,一定先比较左区间,否则在右区间,但是要id+1变为
id+1-tree[rt<<1],表示左区间不符合要求,然后在更新右区间。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 2e5+10;
int tree[maxn<<2],a[maxn],n;
struct Node{
int id,ai;
}cur[maxn];
void Pushup(int rt){
tree[rt] = tree[rt<<1]+tree[rt<<1|1];
}
void Build(int rt,int l,int r){
if(l==r){
tree[rt] = 1;
return ;
}
int mid = (l+r)>>1;
Build(rt<<1,l,mid);
Build(rt<<1|1,mid+1,r);
Pushup(rt);
}
void Update(int x,int y,int rt,int l,int r){
if(l==r){
tree[rt] = 0;
a[l] = y;
return ;
}
int mid = (l+r)>>1;
if(tree[rt<<1]>=x) Update(x,y,rt<<1,l,mid);
else Update(x-tree[rt<<1],y,rt<<1|1,mid+1,r);
Pushup(rt);
}
int main(void){
while(~scanf("%d",&n)){
Build(1,1,n);
for(int i=1;i<=n;i++) scanf("%d%d",&cur[i].id,&cur[i].ai);
for(int i=n;i>=1;i--){
Update(cur[i].id+1,cur[i].ai,1,1,n);
}
for(int i=1;i<=n;i++) printf("%d%c",a[i],(i==n?'\n':' '));
}
return 0;
}