题记:
做法一:暴力做法,时间复杂度O(n2)。
#include<iostream>
using namespace std;
const int N=8010;
int a[N],num[N],ans[N];
int main(){
int n;
cin>>n;
for(int i=2;i<=n;i++) cin>>a[i];
for(int i=n;i>0;i--){
int k=0;
for(int j=1;j<=n;j++){
if(!num[j]){
k++;
if(k==a[i]+1){
ans[i]=j;
num[j]++;
break;
}
}
}
}
for(int i=1;i<=n;i++){
cout<<ans[i]<<endl;
}
return 0;
}
做法二:线段树优化,时间复杂度O(nlogn)
#include<iostream>
using namespace std;
const int N=1e5;
struct Tree{
int l,r,len;
}tree[N];
int pre[N],ans[N];
void BuildTree(int left,int right,int u){
tree[u].l=left;
tree[u].r=right;
tree[u].len=right-left+1;
if(left==right)
return ;
BuildTree(left,(left+right)>>1,u<<1);//递归左子树
BuildTree(((left+right)>>1)+1,right,(u<<1)+1);//递归右子树
}
int query(int u,int num){
tree[u].len--;
if(tree[u].l==tree[u].r)
return tree[u].l;
if(tree[u<<1].len<num)
return query((u<<1)+1,num-tree[u<<1].len);
if(tree[u<<1].len>=num)
return query(u<<1,num);
}
int main(){
int n,i;
cin>>n;
pre[1]=0;
for(int i=2;i<=n;i++)
cin>>pre[i];
BuildTree(1,n,1);
for(int i=n;i>=1;i--)
ans[i]=query(1,pre[i]+1);
for(int i=1;i<=n;i++)
cout<<ans[i]<<endl;
return 0;
}
做法三:完全二叉树实现线段树。
#include<iostream>
#include<cmath>
using namespace std;
const int N=1e5;
int pre[N],tree[4*N],ans[N];
void BuildTree(int n,int last_left){
int i;
for(int i=last_left;i<last_left+n;i++)
tree[i]=1;
while(last_left!=1){
for(int i=last_left/2;i<last_left;i++)
tree[i]=tree[i*2]+tree[i*2+1];
last_left=last_left/2;
}
}
int query(int u,int num,int last_left){
tree[u]--;
if(tree[u]==0&&u>=last_left)
return u;
if(tree[u<<1]<num)
return query((u<<1)+1,num-tree[u<<1],last_left);
if(tree[u<<1]>=num)
return query(u<<1,num,last_left);
}
int main(){
int n,last_left,i;
cin>>n;
pre[1]=0;
last_left=1<<(int(log(n)/log(2))+1);
//找二叉树最后一行的最左边一个,即找离n最近的2的指数
//cout<<last_left<<endl;
for(int i=2;i<=n;i++)
cin>>pre[i];
BuildTree(n,last_left);
for(int i=n;i>=1;i--)
ans[i]=query(1,pre[i]+1,last_left)-last_left+1;
for(int i=1;i<=n;i++)
cout<<ans[i]<<endl;
return 0;
}
做法四:树状数组。
#include<iostream>
using namespace std;
#define lowbit(x) ((x)&-(x))
const int N=1e4;
int a[N],ans[N],tree[N];
int n;
void add(int x,int d){
while(x<=n){
tree[x]+=d;
x+=lowbit(x);
}
}
int sum(int x){
int sum=0;
while(x>0){
sum+=tree[x];
x-=lowbit(x);
}
return sum;
}
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(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n;
a[1]=0;
for(int i=2;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
tree[i]=lowbit(i);
for(int i=n;i>0;i--){
int x=findpos(a[i]+1);
add(x,-1);
ans[i]=x;
}
for(int i=1;i<=n;i++)
cout<<ans[i]<<endl;
return 0;
}