题目链接:构造数组
我们从后往前考虑,如果当前加入的数字的下标为pos,那么我们就是相当于在当前操作和之前操作插入的数字的第pos个位置。
所以我们其实就是动态第k大的位置。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=5e5+10;
int n,id[N],a[N],sum[N<<2],res[N];
#define mid (l+r>>1)
void build(int p,int l,int r){
if(l==r){sum[p]=1; return ;}
build(p<<1,l,mid),build(p<<1|1,mid+1,r);
sum[p]=sum[p<<1]+sum[p<<1|1];
}
void change(int p,int l,int r,int x){
if(l==r){sum[p]=0; return ;}
if(x<=mid) change(p<<1,l,mid,x);
else change(p<<1|1,mid+1,r,x);
sum[p]=sum[p<<1]+sum[p<<1|1];
}
int ask(int p,int l,int r,int k){
if(l==r) return l;
if(sum[p<<1]>=k) return ask(p<<1,l,mid,k);
else return ask(p<<1|1,mid+1,r,k-sum[p<<1]);
}
signed main(){
cin>>n; build(1,1,n);
for(int i=1;i<=n;i++) scanf("%d %d",&id[i],&a[i]);
for(int i=n;i>=1;i--){
int pos=ask(1,1,n,id[i]);
res[pos]=a[i]; change(1,1,n,pos);
}
for(int i=1;i<=n;i++) printf("%d ",res[i]);
return 0;
}