题目来源:点击打开链接
用线段树记录总的空位置数,倒着将价值插入,倒着插一边就是最终的位置
#include <stdio.h>
#define maxn 200005
int p[maxn], v[maxn], sta[maxn];
struct
{
int l,r,s;
}node[maxn*4];
void buildtree(int left, int right, int u)
{
node[u].l = left;
node[u].r = right;
if(left == right)
{
node[u].s = 1;//初始化每个空位置都记为1
return;
}
int mid = (left + right)/2;
buildtree(left, mid, 2*u);
buildtree(mid+1, right, 2*u+1);
node[u].s = node[2*u].s + node[2*u+1].s;
}
void query(int pi, int vi, int left, int right, int u)
{
if(left == right)
{
node[u].s=0;//插入某个元素之后该位置数值变为0
sta[left] = vi;
return;
}
int mid = (left + right)/2;
if(node[2*u].s>=pi)
query(pi, vi, left, mid, u<<1);
//如果左子树的空格数大于序号,就放左边,否则就放右边,
//但由于左边有一些空位置 ,只要搜右子树的部分空位置即可
//只要左右两边的空位置之和加在一起等于序号数即可
else
query(pi-node[2*u].s, vi, mid+1, right, u<<1|1);
node[u].s = node[u<<1].s + node[u<<1|1].s;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
buildtree(1,n,1);
for(int i=1; i<=n; i++)
{
scanf("%d%d",&p[i], &v[i]);
}
for(int i=n;i>=1;i--)
{
query(p[i]+1, v[i], 1, n, 1);//倒着来记录sta上的数字
}
for(int i=1;i<n;i++)
{
printf("%d ",sta[i]);
}
printf("%d\n",sta[n]);
}
return 0;
}