之前做过一个Buy tickets,和这道题差不多,就是按照倒序删除第i个点,线段树实现
CODE
#include<iostream>
#define L 2*u
#define R 2*u+1
using namespace std;
int a[8001];
struct tree
{
int l,r,cnt;
}t[10000];
int stack[8001];
void Build(int s,int e,int u)
{
t[u].l=s;
t[u].r=e;
t[u].cnt=e-s+1;
if(s<e)
{
Build(s,(s+e)>>1,L);
Build((s+e)/2+1,e,R);
}
}
void del(int num,int u)
{
if(t[u].l==t[u].r)
{
t[u].cnt=0;
stack[++stack[0]]=t[u].r;
return ;
}
if(num<=t[L].cnt)//如果左子树>=num,则从左子树删除,否则从右子树删除第num-t[L].cnt个
del(num,L);
else
del(num-t[L].cnt,R);
t[u].cnt--;
}
int main()
{
int i,n;
scanf("%d",&n);
for(i=n-1;i>=1;i--)
{
scanf("%d",&a[i]);
a[i]+=1;
}
a[n]=1;
Build(1,n,1);
for(i=1;i<=n;i++)
{
del(a[i],1);
}
for(i=stack[0];i>=1;i--)
printf("%d\n",stack[i]);
}