
树状数组+二分
sum(x)返回x之前有多少个点已经被取走了,a[i]+1为左边界,n为右边界,判断sum(x)和(x-1-a[i])大小即可
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5+10;
int n;
int a[N],tr[N];
int lowbit(int x){
return x & -x;
}
void add(int x,int c){
for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=c;
}
int sum(int x){
int res=0;
for(int i=x;i>=1;i-=lowbit(i)) res+=tr[i];
return res;
}
int binary_search(int x){
int l=x,r=n;
while(l<r){
int mid=l+r>>1;
if(sum(mid)<=mid-x) r=mid;
else l=mid+1;
}
return l;
}
int main(){
cin>>n;
LL tot=(LL)(1+n)*n/2;
sizeof(tr,0,sizeof tr);
for(int i=2;i<=n;i++){
cin>>a[i];
}
vector<int> ans;
for(int i=n;i>=2;i--){
int cur=binary_search(a[i]+1);
tot-=(LL)cur;
ans.push_back(cur);
add(cur,1);
}
cout<<tot<<endl;
for(int i=n-2;i>=0;i--) cout<<ans[i]<<endl;
return 0;
}