這道題用樹狀數組作比較好,雖然樹狀數組能作的線段樹也能夠作到,可是樹狀數組更簡潔方便,易操做ios
原理即是第x個數的二進制數最後一個「1」,決定tree的結點的長度數組
好比:spa
sum[3]=tree[3]+tree[2];it
sum[4]=tree[4];io
sum[5]=tree[5]+tree[4];stream
分割是位運算裏的操做,一個數和它負數的補碼(取反+1)用x&-x求得二進制數中爲「1」的最小位原理
代碼以下:二進制
#include <iostream>
#include <cstdio>
#define lowbit(x) ((x)&-(x))
using namespace std;
const int MAX=10000;
int n;
int tree[MAX],pre[MAX],ans[MAX];di
void add(int x,int d){//給x加d
while(x<=n){
tree[x]+=d;
x+=lowbit(x);
}
}while
int sum(int x){
int ans=0;
while(x){
ans+=tree[x];
x-=lowbit(x);
}
return ans;
}
int findpos(int x){
int l=1,r=n;
while(l<r){
int mid=(l+r)>>1;
if(sum(mid)<x){
l=mid+1;
}
else{
r=mid;
}
}
return l;
}
int main(){ scanf("%d",&n); pre[1]=0; for(int i=2;i<=n;i++){ scanf("%d",&pre[i]); } for(int i=1;i<=n;i++){//初始化不須要add() tree[i]=lowbit(i); } for(int i=n;i>0;i--){ int x=findpos(pre[i]+1); add(x,-1); ans[i]=x; } for(int i=1;i<=n;i++){ printf("%d\n",ans[i]); } return 0;}