#include<bits/stdc++.h>
using namespace std;
void __p(int x) {cerr<<x;}
void __p(long long x){cerr<<x;}
void __p(double x){cerr<<x;}
void _print(){cerr<<"]\n";}
template<typename T,typename... V>//
void _print(T t,V... v){__p(t);if(sizeof...(v))cerr<<",";_print(v...);}
#define debug(x...) cerr<<"["<<#x<<"] = ["; _print(x)
#define see1 cout<<"*************\n";
#define see2 cerr<<"*************\n";
#define int long long
#define endl '\n'
const int N=5e5+10;
int tr[N],n;/*注意树状数组实际使用范围n,定义成全局变量*/
void add(int x,int k){
while(x<=n){
tr[x]+=k;
x+=x&-x;
}
}
int sum(int x){
int ans=0;
while(x>0){/*注意x>0,不能==0*/
ans+=tr[x];
x-=x&-x;
}
return ans;
}
bool check(int x,int k){
if(sum(x)>=k) return 1;
return 0;
}
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n;
vector<int>a(n+1),ans=a;
for(int i=1;i<=n;i++){
cin>>a[i];
add(i,1);
}
//将1,2,3,...,n插入一个空的数组中去,对于任意的i,其位置不受1,2,3...i-1这些数的位置的影响,与i+1,i+2,...,n这些数的位置有关,那么先考虑n的位置,ans[n]=p[n],而n-1的位置,在确定n位置后,将其去除掉后,
//剩下的空位置中,从小到大第p[n-1]个即n-1的位置,以此类推。数据结构上,用树状数组辅助实现,查找使用二分.实现了在一个动态修改(插入or删除)的数组(该数组必须是有序的)中进行第k个元素的查找、询问操作
for(int i=n;i;i--){
int l=1,r=n;
while(l<r){
// see2;
int mid=l+r>>1;
if(check(mid,a[i])) r=mid;
else l=mid+1;
}
ans[i]=l;
add(l,-1);
}
for(int i=1;i<=n;i++)
a[ans[i]]=i;
for(int i=1;i<=n;i++)
cout<<a[i]<<' ';
}
树状数组 - OI Wiki #单点修改,全局查询第k小
25/2/20