Sample Input
4
0 77
1 51
1 33
2 69
4
0 20523
1 19243
1 3890
0 31492
Sample Output
77 33 69 51
31492 20523 3890 19243
emmm。不知道说什么好。。以后再说吧。。。
每个数的位置dex[i]++。插在第dex[i]的空格上。根据这个值判断插入到哪个子树中。
#include <cstdio>
using namespace std;
const int N=200005*4;
int sum[N],ans[N]; //sum[]是指区间空格数
int dex[N],x[N];
void build(int l,int r,int pos)
{
if(l==r)
{
sum[pos]=1;
return;
}
int mid=(l+r)>>1;
build(l,mid,pos<<1);
build(mid+1,r,pos<<1|1);
sum[pos]=sum[pos<<1]+sum[pos<<1|1];
}
void update(int num,int val,int l,int r,int pos)
{
if(l==r)
{
sum[pos]=0; //该点存放val这个数 则该点区间的空格数为0;
ans[l]=val; //储存该点的信息。注意是ans[l]=val;
return;
}
int mid=(l+r)>>1;
if(sum[pos<<1]>=num) //左子树的空格不够
update(num,val,l,mid,pos<<1);
else
update(num-sum[pos<<1],val,mid+1,r,pos<<1|1);//插到右子树第num-sum[pos<<1]个空格中
sum[pos]=sum[pos<<1]+sum[pos<<1|1];
}
int main()
{
int n;
while(~scanf("%d",&n))
{
build(1,n,1);
for(int i=1;i<=n;i++)
scanf("%d%d",&dex[i],&x[i]);
for(int i=n;i>=1;i--)
update(dex[i]+1,x[i],1,n,1);
for(int i=1;i<=n;i++)
printf("%d%c",ans[i],(i==n)?'\n':' ');
}
}