#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mk make_pair
#define ll long long
#define F first
#define S second
const int MX=2e5+22;
int N, M, k;
int arr[MX];
int an[MX];
int vis[MX];
ll st[MX*4];
void up(int L, int R, int p, int i, int j, int val)
{
    if(L > R || L > i || R < j) return ;
    if(L >= i && R <= j)
    {
        st[p]=val;
        return;
    }
    int m=(L+R)>>1;
    up(L, m, p<<1, i, j, val);
    up(m+1, R, p<<1|1, i, j, val);
    st[p]=st[p<<1]+st[p<<1|1];
}
ll cursum=0;
int q(int L, int R, int p, ll need)
{
    if(L == R)
    {
        return L;
    }
    int m=(L+R)>>1;
    if(cursum + st[p<<1] <= need)
    {
        cursum += st[p<<1] ;
        return q(m+1, R, p<<1|1, need);
    }
    return q(L, m, p<<1, need);
}
void solve()
{
    ll sum=0;
    scanf("%d", &N);
    for(int i=0; i<N; i++)
    {
        scanf("%d", &arr[i]);
        up(1, N, 1, i+1, i+1, i+1);
    }
    for(int i=N-1; i>=0; i--)
    {
        cursum=0;
        ll c=q(1, N, 1,arr[i]);
        an[i]=c;
        assert(cursum == arr[i]);
        up(1, N, 1, c, c, 0);
//        continue;
//        ll c=0, sum=0;
//        while(1)
//        {
//            ++c;
//            if(vis[c]) continue;
//            sum+=c;
//            if(sum > arr[i])
//            {
//                vis[c]=1;
//                an[i]=c;
//                break;
//            }
//        }
    }
    for(int i=0; i<N; i++) cout<<an[i]<<" ";
}
int main()
{
    int T=1;
//    cin>>T;
    while(T--) solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mk make_pair
#define ll long long
#define F first
#define S second
const int MX=2e5+22;
int N, M, k;
ll arr[MX];
int an[MX];
int vis[MX];
ll st[MX*4];
void up(int L, int R, int p, int i, int j, int val)
{
    if(L > R || L > i || R < j) return ;
    if(L >= i && R <= j)
    {
        st[p]=val;
        return;
    }
    int m=(L+R)>>1;
    up(L, m, p<<1, i, j, val);
    up(m+1, R, p<<1|1, i, j, val);
    st[p]=st[p<<1]+st[p<<1|1];
}
ll cursum=0;
int q(int L, int R, int p, ll need)
{
    if(L == R)
    {
        return L;
    }
    int m=(L+R)>>1;
    if(cursum + st[p<<1] <= need)
    {
        cursum += st[p<<1] ;
        return q(m+1, R, p<<1|1, need);
    }
    return q(L, m, p<<1, need);
}
void solve()
{
    ll sum=0;
    scanf("%d", &N);
    for(int i=0; i<N; i++)
    {
        /// shit long long
        scanf("%lld", &arr[i]);
        up(1, N, 1, i+1, i+1, i+1);
    }
    for(int i=N-1; i>=0; i--)
    {
        cursum=0;
        ll c=q(1, N, 1,arr[i]);
        an[i]=c;
        up(1, N, 1, c, c, 0);
    }
    for(int i=0; i<N; i++) cout<<an[i]<<" ";
}
int main()
{
    int T=1;
//    cin>>T;
    while(T--) solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mk make_pair
#define ll long long
#define F first
#define S second
const int MX=2e5+22;
int N, M, k;
int arr[MX];
int an[MX];
int vis[MX];
ll st[MX*4];
void up(int L, int R, int p, int i, int j, int val)
{
    if(L > R || L > i || R < j) return ;
    if(L >= i && R <= j)
    {
        st[p]=val;
        return;
    }
    int m=(L+R)>>1;
    up(L, m, p<<1, i, j, val);
    up(m+1, R, p<<1|1, i, j, val);
    st[p]=st[p<<1]+st[p<<1|1];
}
ll cursum=0;
int q(int L, int R, int p, ll need)
{
    if(L == R)
    {
        return L;
    }
    int m=(L+R)>>1;
    if(cursum + st[p<<1] <= need)
    {
        cursum += st[p<<1] ;
        return q(m+1, R, p<<1|1, need);
    }
    return q(L, m, p<<1, need);
}
void solve()
{
    ll sum=0;
    scanf("%d", &N);
    for(int i=0; i<N; i++)
    {
        scanf("%d", &arr[i]);
        up(1, N, 1, i+1, i+1, i+1);
    }
    for(int i=N-1; i>=0; i--)
    {
        cursum=0;
        ll c=q(1, N, 1,arr[i]);
        an[i]=c;
//        assert(cursum == arr[i]);
        up(1, N, 1, c, c, 0);
//        continue;
//        ll c=0, sum=0;
//        while(1)
//        {
//            ++c;
//            if(vis[c]) continue;
//            sum+=c;
//            if(sum > arr[i])
//            {
//                vis[c]=1;
//                an[i]=c;
//                break;
//            }
//        }
    }
    for(int i=0; i<N; i++) cout<<an[i]<<" ";
}
int main()
{
    int T=1;
//    cin>>T;
    while(T--) solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mk make_pair
#define ll long long
#define F first
#define S second
const int MX=2e5+22;
int N, M, k;
int arr[MX];
int an[MX];
int vis[MX];
void solve()
{
    ll sum=0;
    scanf("%d", &N);
    for(int i=0;i<N;i++)
    {
        scanf("%d", &arr[i]);
    }
    for(int i=N-1;i>=0;i--)
    {
        ll c=0, sum=0;
        while(1)
        {
            ++c;
            if(vis[c]) continue;
            sum+=c;
            if(sum > arr[i])
            {
                vis[c]=1;
                an[i]=c;
                break;
            }
        }
    }
    for(int i=0;i<N;i++) cout<<an[i]<<" ";
}
int main()
{
    int T=1;
//    cin>>T;
    while(T--) solve();
    return 0;
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 200100
#define ls id<<1
#define rs id<<1|1
#define mid ((l+r)>>1)
using namespace std;
int n,a[N],c[N],s[N<<2],lazy[N<<2],cnt;
void up(int id){s[id]=min(s[ls],s[rs]);}
void  build(int id,int l,int r)
{
	if(l==r){s[id]=a[l];return ;}
	build(ls,l,mid),build(rs,mid+1,r);
	up(id);
}
void down(int id)
{
	s[ls]-=lazy[id],s[rs]-=lazy[id];
	lazy[ls]+=lazy[id],lazy[rs]+=lazy[id];
	lazy[id]=0;
}
int get(int id,int l,int r)
{
	if(l==r){s[id]=1e9;return l;}
	if(lazy[id])down(id);
	if(s[rs]==0)return get(rs,mid+1,r);
	else return get(ls,l,mid);
}
void add(int id,int l,int r,int x,int y,int z)
{//puts("1111");
	if(l==x&&r==y){s[id]-=z;lazy[id]+=z;return ;}
//	if(++cnt<=10)printf("%d %d %d %d %d\n",id,l,r,x,y);
	if(y<=mid)add(ls,l,mid,x,y,z);
	else if(x>mid)add(rs,mid+1,r,x,y,z);
	else add(ls,l,mid,x,mid,z),add(rs,mid+1,r,mid+1,y,z);
	up(id);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	build(1,1,n);
	for(int i=1;i<=n;i++)
	{
		int x=get(1,1,n);
	//	printf("%d\n",x);
		c[x]=i;
		if(x+1>n)continue;
		add(1,1,n,x+1,n,i);
	}
	for(int i=1;i<=n;i++)printf("%d ",c[i]);
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 2001000
#define ls id<<1
#define rs id<<1|1
#define mid ((l+r)>>1)
using namespace std;
int n,a[N],s[N<<2],lazy[N<<2],c[N];
void up(int id){s[id]=min(s[ls],s[rs]);}
void build(int id,int l,int r)
{
	if(l==r){s[id]=a[l];return ;}
	build(ls,l,mid),build(rs,mid+1,r);
	up(id);
}
void add(int id,int l,int r,int x,int y,int z)
{
	if(l==x&&r==y){s[id]-=z;lazy[id]+=z;return ;}
	if(y<=mid)add(ls,l,mid,x,y,z);
	else if(x>mid)add(rs,mid+1,r,x,y,z);
	else add(ls,l,mid,x,mid,z),add(rs,mid+1,r,mid+1,y,z);
	up(id);
}
void down(int id)
{
	s[ls]-=lazy[id],s[rs]-=lazy[id];
	lazy[ls]+=lazy[id],lazy[rs]+=lazy[id];
	lazy[id]=0;
}
int get(int id,int l,int r)
{
	if(l==r){s[id]=1e9;return l;}
	if(lazy[id])down(id);
	if(s[rs]==0)return get(rs,mid+1,r);
	else return get(ls,l,mid);
	up(id);
}
int get1(int id,int l,int r,int x)
{
	if(l==r){return s[id];}
	if(lazy[id])down(id);
	if(x>mid)return get1(rs,mid+1,r,x);
	else return get1(ls,l,mid,x);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	build(1,1,n);
	for(int i=1;i<=n;i++)
	{
		int x=get(1,1,n);
		c[x]=i;
//		printf("%d\n",x);
//		printf("!%d\n",get1(1,1,n,5));
		if(x+1<=n)
		add(1,1,n,x+1,n,i);
	}
	for(int i=1;i<=n;i++)printf("%d ",c[i]);
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 200100
#define ls id<<1
#define rs id<<1|1
#define int long long
#define mid ((l+r)>>1)
using namespace std;
int n,a[N],c[N],s[N<<2],lazy[N<<2];
void up(int id){s[id]=min(s[ls],s[rs]);}
void down(int id)
{
	s[ls]-=lazy[id],s[rs]-=lazy[id];
	lazy[ls]+=lazy[id],lazy[rs]+=lazy[id];
	lazy[id]=0;
}
void build(int id,int l,int r)
{
//	printf("%d %d %d\n",id,ls,rs);
	if(l==r){s[id]=a[l];return ;}
	build(ls,l,mid),build(rs,mid+1,r);
	up(id);
}
void add(int id,int l,int r,int x,int y,int z)
{
	if(l==x&&r==y){s[id]-=z,lazy[id]+=z;return ;}
	if(y<=mid)add(ls,l,mid,x,y,z);
	else if(x>mid)add(rs,mid+1,r,x,y,z);
	else add(ls,l,mid,x,mid,z),add(rs,mid+1,r,mid+1,y,z);
	up(id);
}
int get(int id,int l,int r)
{
	if(l==r){s[id]=1e18;return l;}
	if(lazy[id])down(id);
	if(!s[rs])
	{
		int x=get(rs,mid+1,r);
		up(id);return x;
	}else
	{
		int x=get(ls,l,mid);
		up(id);return x;
	}
}
int get1(int id,int l,int r,int x)
{
	if(l==r){return s[id];}
	if(lazy[id])down(id);
	if(x>mid)return get(rs,mid+1,r);
	else return get(ls,l,mid);
}
signed main()
{
	scanf("%I64d",&n);
	for(int i=1;i<=n;i++)scanf("%I64d",&a[i]);
	build(1,1,n);
	for(int i=1;i<=n;i++)
	{
		int x=get(1,1,n);
		c[x]=i;
		if(x+1<=n)
		add(1,1,n,x+1,n,i);
	}
	for(int i=1;i<=n;i++)printf("%I64d ",c[i]);
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 2001000
#define ls id<<1
#define rs id<<1|1
#define mid ((l+r)>>1)
using namespace std;
int n,a[N],s[N<<2],lazy[N<<2],c[N];
void up(int id){s[id]=min(s[ls],s[rs]);}
void build(int id,int l,int r)
{
	if(l==r){s[id]=a[l];return ;}
	build(ls,l,mid),build(rs,mid+1,r);
	up(id);
}
void add(int id,int l,int r,int x,int y,int z)
{
	if(l==x&&r==y){s[id]-=z;lazy[id]+=z;return ;}
	if(y<=mid)add(ls,l,mid,x,y,z);
	else if(x>mid)add(rs,mid+1,r,x,y,z);
	else add(ls,l,mid,x,mid,z),add(rs,mid+1,r,mid+1,y,z);
	up(id);
}
void down(int id)
{
	s[ls]-=lazy[id],s[rs]-=lazy[id];
	lazy[ls]+=lazy[id],lazy[rs]+=lazy[id];
	lazy[id]=0;
}
int get(int id,int l,int r)
{
	if(l==r){s[id]=1e9;return l;}
	if(lazy[id])down(id);
	if(s[rs]==0)return get(rs,mid+1,r);
	else return get(ls,l,mid);
}
int get1(int id,int l,int r,int x)
{
	if(l==r){return s[id];}
	if(lazy[id])down(id);
	if(x>mid)return get1(rs,mid+1,r,x);
	else return get1(ls,l,mid,x);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	build(1,1,n);
	for(int i=1;i<=n;i++)
	{
		int x=get(1,1,n);
		c[x]=i;
//		printf("%d\n",x);
//		printf("!%d\n",get1(1,1,n,5));
		if(x+1<=n)
		add(1,1,n,x+1,n,i);
	}
	for(int i=1;i<=n;i++)printf("%d ",c[i]);
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 200100
#define ls id<<1
#define rs id<<1|1

#define mid ((l+r)>>1)
using namespace std;
int n,a[N],c[N],s[N<<2],lazy[N<<2];
void up(int id){s[id]=min(s[ls],s[rs]);}
void down(int id)
{
	s[ls]-=lazy[id],s[rs]-=lazy[id];
	lazy[ls]+=lazy[id],lazy[rs]+=lazy[id];
	lazy[id]=0;
}
void build(int id,int l,int r)
{
//	printf("%d %d %d\n",id,ls,rs);
	if(l==r){s[id]=a[l];return ;}
	build(ls,l,mid),build(rs,mid+1,r);
	up(id);
}
void add(int id,int l,int r,int x,int y,int z)
{
//	printf("++%d %d %d %d\n",id,l,r,s[id]);
	if(l==x&&r==y){s[id]-=z,lazy[id]+=z;return ;}
	if(y<=mid)add(ls,l,mid,x,y,z);
	else if(x>mid)add(rs,mid+1,r,x,y,z);
	else add(ls,l,mid,x,mid,z),add(rs,mid+1,r,mid+1,y,z);
	up(id);
//	if(id==3)printf("****%d\n",s[id]);
}
int get(int id,int l,int r)
{
//	printf("--%d %d %d %d\n",id,l,r,s[id]);
	if(l==r){s[id]=1e9;return l;}
	if(lazy[id])down(id);
	if(!s[rs])
	{
		int x=get(rs,mid+1,r);
		up(id);return x;
	}else
	{
		int x=get(ls,l,mid);
		up(id);return x;
	}
}
int get1(int id,int l,int r,int x)
{
	if(l==r){return s[id];}
	if(lazy[id])down(id);
	if(x>mid)return get(rs,mid+1,r);
	else return get(ls,l,mid);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	build(1,1,n);
//	for(int i=1;i<=4*n;i++)printf("%d %d\n",i,s[i]);
	for(int i=1;i<=n;i++)
	{
//		puts("-----");
//		if(i==3)printf("$%d %d %d\n",s[3],s[6],s[7]);
		int x=get(1,1,n);
		c[x]=i;
//		printf("!%d\n",x);
		if(x+1<=n)
//		puts("++++"),
		add(1,1,n,x+1,n,i);
	//	for(int j=1;j<=n;j++)printf("%d ",get1(1,1,n,j));
	}
	for(int i=1;i<=n;i++)printf("%d ",c[i]);
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 200100
#define ls id<<1
#define rs id<<1|1
#define int long long
#define mid ((l+r)>>1)
using namespace std;
int n,a[N],c[N],s[N<<2],lazy[N<<2];
void up(int id){s[id]=min(s[ls],s[rs]);}
void down(int id)
{
	s[ls]-=lazy[id],s[rs]-=lazy[id];
	lazy[ls]+=lazy[id],lazy[rs]+=lazy[id];
	lazy[id]=0;
}
void build(int id,int l,int r)
{
//	printf("%d %d %d\n",id,ls,rs);
	if(l==r){s[id]=a[l];return ;}
	build(ls,l,mid),build(rs,mid+1,r);
	up(id);
}
void add(int id,int l,int r,int x,int y,int z)
{
//	printf("++%d %d %d %d\n",id,l,r,s[id]);
	if(l==x&&r==y){s[id]-=z,lazy[id]+=z;return ;}
	if(y<=mid)add(ls,l,mid,x,y,z);
	else if(x>mid)add(rs,mid+1,r,x,y,z);
	else add(ls,l,mid,x,mid,z),add(rs,mid+1,r,mid+1,y,z);
	up(id);
//	if(id==3)printf("****%d\n",s[id]);
}
int get(int id,int l,int r)
{
//	printf("--%d %d %d %d\n",id,l,r,s[id]);
	if(l==r){s[id]=1e9;return l;}
	if(lazy[id])down(id);
	if(!s[rs])
	{
		int x=get(rs,mid+1,r);
		up(id);return x;
	}else
	{
		int x=get(ls,l,mid);
		up(id);return x;
	}
}
int get1(int id,int l,int r,int x)
{
	if(l==r){return s[id];}
	if(lazy[id])down(id);
	if(x>mid)return get(rs,mid+1,r);
	else return get(ls,l,mid);
}
signed main()
{
	scanf("%I64d",&n);
	for(int i=1;i<=n;i++)scanf("%I64d",&a[i]);
	build(1,1,n);
//	for(int i=1;i<=4*n;i++)printf("%d %d\n",i,s[i]);
	for(int i=1;i<=n;i++)
	{
//		puts("-----");
//		if(i==3)printf("$%d %d %d\n",s[3],s[6],s[7]);
		int x=get(1,1,n);
		c[x]=i;
//		printf("!%d\n",x);
		if(x+1<=n)
//		puts("++++"),
		add(1,1,n,x+1,n,i);
	//	for(int j=1;j<=n;j++)printf("%d ",get1(1,1,n,j));
	}
	for(int i=1;i<=n;i++)printf("%I64d ",c[i]);
}


#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int maxn=2e5+5;
const ll inf=0x3f3f3f3f3f3f;
int  n,ans[maxn];
ll Min(ll a,ll b)
{return a>b?b:a;}
ll a[maxn];
struct Segmenttree
{
	struct node
	{
		int l,r;
		ll v,lazy;
	}tree[maxn<<3];
	void build(int p,int l,int r)
	{
		tree[p].l=l;
		tree[p].r=r;
		if(l==r){tree[p].v=a[l];return;}
		int mid=l+r>>1;
		build(p<<1,l,mid);
		build(p<<1|1,mid+1,r);
		tree[p].v=Min(tree[p<<1].v,tree[p<<1|1].v);
	}
	inline void putdown(int p)
	{
		tree[p<<1].v+=tree[p].lazy;
		tree[p<<1|1].v+=tree[p].lazy;
		tree[p<<1].lazy+=tree[p].lazy;
		tree[p<<1|1].lazy+=tree[p].lazy;
		tree[p].lazy=0;
	}
	int query(int p)
	{
		if(tree[p].l==tree[p].r)return tree[p].l;
		int mid=tree[p].l+tree[p].r>>1;
		if(tree[p].lazy)putdown(p);
		if(tree[p<<1|1].v==0)return query(p<<1|1);
		else return query(p<<1);
	}
	void modify(int p,int x,int y,ll d)
	{
		if(x<=tree[p].l&&tree[p].r<=y)
		{
			tree[p].v+=d;
			tree[p].lazy+=d;
			return ;
		}
		if(tree[p].lazy)putdown(p);
		int mid=tree[p].l+tree[p].r>>1;
		if(x<=mid&&y>=tree[p].l)modify(p<<1,x,y,d);
		if(y>mid&&x<=tree[p].r)modify(p<<1|1,x,y,d);
		tree[p].v=Min(tree[p<<1].v,tree[p<<1|1].v);
	}
}segmenttree;

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)cin>>a[i];
	segmenttree.build(1,1,n);
	for(int i=1;i<=n;i++)
	{
		int x=segmenttree.query(1);
		segmenttree.modify(1,x,x,inf);
		ans[x]=i;
		if(x<n)segmenttree.modify(1,x+1,n,-i);
	}
	for(int i=1;i<=n;i++)printf("%d ",ans[i]);
}


#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int maxn=2e5+5;
const ll inf=maxn*maxn/2;
int  n,ans[maxn];
ll Min(ll a,ll b)
{return a>b?b:a;}
ll a[maxn];
struct Segmenttree
{
	struct node
	{
		int l,r;
		ll v,lazy;
	}tree[maxn<<3];
	void build(int p,int l,int r)
	{
		tree[p].l=l;
		tree[p].r=r;
		if(l==r){tree[p].v=a[l];return;}
		int mid=l+r>>1;
		build(p<<1,l,mid);
		build(p<<1|1,mid+1,r);
		tree[p].v=Min(tree[p<<1].v,tree[p<<1|1].v);
	}
	inline void putdown(int p)
	{
		tree[p<<1].v+=tree[p].lazy;
		tree[p<<1|1].v+=tree[p].lazy;
		tree[p<<1].lazy+=tree[p].lazy;
		tree[p<<1|1].lazy+=tree[p].lazy;
		tree[p].lazy=0;
	}
	int query(int p)
	{
		if(tree[p].l==tree[p].r)return tree[p].l;
		int mid=tree[p].l+tree[p].r>>1;
		if(tree[p].lazy)putdown(p);
		if(tree[p<<1|1].v==0)return query(p<<1|1);
		else return query(p<<1);
	}
	void modify(int p,int x,int y,ll d)
	{
		if(x<=tree[p].l&&tree[p].r<=y)
		{
			tree[p].v+=d;
			tree[p].lazy+=d;
			return ;
		}
		if(tree[p].lazy)putdown(p);
		int mid=tree[p].l+tree[p].r>>1;
		if(x<=mid&&y>=tree[p].l)modify(p<<1,x,y,d);
		if(y>mid&&x<=tree[p].r)modify(p<<1|1,x,y,d);
		tree[p].v=Min(tree[p<<1].v,tree[p<<1|1].v);
	}
}segmenttree;

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%I64d",&a[i]);
	segmenttree.build(1,1,n);
	for(int i=1;i<=n;i++)
	{
		int x=segmenttree.query(1);
		segmenttree.modify(1,x,x,inf);
		ans[x]=i;
		if(x<n)segmenttree.modify(1,x+1,n,-i);
	}
	for(int i=1;i<=n;i++)printf("%d ",ans[i]);
}


#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int maxn=2e5+5;
const ll inf=maxn*maxn/2;
int  n,ans[maxn];
ll Min(ll a,ll b)
{return a>b?b:a;}
ll a[maxn];
struct Segmenttree
{
	struct node
	{
		int l,r;
		ll v,lazy;
	}tree[maxn<<3];
	void build(int p,int l,int r)
	{
		tree[p].l=l;
		tree[p].r=r;
		if(l==r){tree[p].v=a[l];return;}
		int mid=l+r>>1;
		build(p<<1,l,mid);
		build(p<<1|1,mid+1,r);
		tree[p].v=Min(tree[p<<1].v,tree[p<<1|1].v);
	}
	inline void putdown(int p)
	{
		tree[p<<1].v+=tree[p].lazy;
		tree[p<<1|1].v+=tree[p].lazy;
		tree[p<<1].lazy+=tree[p].lazy;
		tree[p<<1|1].lazy+=tree[p].lazy;
		tree[p].lazy=0;
	}
	int query(int p)
	{
		if(tree[p].l==tree[p].r)return tree[p].l;
		int mid=tree[p].l+tree[p].r>>1;
		if(tree[p].lazy)putdown(p);
		if(tree[p<<1|1].v==0)return query(p<<1|1);
		else return query(p<<1);
	}
	void modify(int p,int x,int y,ll d)
	{
		if(x<=tree[p].l&&tree[p].r<=y)
		{
			tree[p].v+=d;
			tree[p].lazy+=d;
			return ;
		}
		int mid=tree[p].l+tree[p].r>>1;
		if(x<=mid&&y>=tree[p].l)modify(p<<1,x,y,d);
		if(y>mid&&x<=tree[p].r)modify(p<<1|1,x,y,d);
		tree[p].v=Min(tree[p<<1].v,tree[p<<1|1].v);
	}
}segmenttree;

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%I64d",&a[i]);
	segmenttree.build(1,1,n);
	for(int i=1;i<=n;i++)
	{
		int x=segmenttree.query(1);
		segmenttree.modify(1,x,x,inf);
		ans[x]=i;
		if(x<n)segmenttree.modify(1,x+1,n,-i);
	}
	for(int i=1;i<=n;i++)printf("%d ",ans[i]);
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
const ll inf=0x3f3f3f3f3f3f;
int n,a[maxn],ans[maxn];
ll Min(ll a,ll b)
{return a>b?b:a;}
struct Segmenttree
{
	struct node
	{
		int l,r;
		ll v,lazy;
	}tree[maxn<<3];
	void build(int p,int l,int r)
	{
		tree[p].l=l;
		tree[p].r=r;
		if(l==r){tree[p].v=a[l];return;}
		int mid=l+r>>1;
		build(p<<1,l,mid);
		build(p<<1|1,mid+1,r);
		tree[p].v=Min(tree[p<<1].v,tree[p<<1|1].v);
	}
	inline void putdown(int p)
	{
		tree[p<<1].v+=tree[p].lazy;
		tree[p<<1|1].v+=tree[p].lazy;
		tree[p<<1].lazy+=tree[p].lazy;
		tree[p<<1|1].lazy+=tree[p].lazy;
		tree[p].lazy=0;
	}
	int query(int p)
	{
		if(tree[p].l==tree[p].r)return tree[p].l;
		int mid=tree[p].l+tree[p].r>>1;
		if(tree[p].lazy)putdown(p);
		if(tree[p<<1|1].v==0)return query(p<<1|1);
		else return query(p<<1);
	}
	void modify(int p,int x,int y,ll d)
	{
		if(x<=tree[p].l&&tree[p].r<=y)
		{
			tree[p].v+=d;
			tree[p].lazy+=d;
			return ;
		}
		int mid=tree[p].l+tree[p].r>>1;
		if(x<=mid&&y>=tree[p].l)modify(p<<1,x,y,d);
		if(y>mid&&x<=tree[p].r)modify(p<<1|1,x,y,d);
		tree[p].v=Min(tree[p<<1].v,tree[p<<1|1].v);
	}
}segmenttree;

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%I64d",&a[i]);
	segmenttree.build(1,1,n);
	for(int i=1;i<=n;i++)
	{
		int x=segmenttree.query(1);
		segmenttree.modify(1,x,x,inf);
		ans[x]=i;
		if(x<n)segmenttree.modify(1,x+1,n,-i);
	}
	for(int i=1;i<=n;i++)printf("%d ",ans[i]);
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
typedef unsigned long long ll;
ll s[maxn],c[maxn];
#define lowbit(x) (x&-x)
int n,ans[maxn];
void modify(int x,ll d)
{for(x;x<=n;x+=lowbit(x))c[x]+=d;}
int ask(ll sum)
{
	ll tmp=0;
	int num=0;
	for(int i=21;i>=0;i--)
	if(num+(1<<i)<=n&&(tmp+c[num+(1<<i)]<=sum))
	{
		num+=1<<i;
		tmp+=c[num];
	}
	return num+1;
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++){cin>>s[i];modify(i,i);}
	for(int i=n;i;i--)
	{
		int x=ask(s[i]);
		ans[i]=x;
		modify(x,-x);
	}
	for(int i=1;i<=n;i++)printf("%d ",ans[i]);
}


#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int maxn=2e5+5;
const ll inf=maxn*maxn/2;
int n,a[maxn],ans[maxn];
ll Min(ll a,ll b)
{return a>b?b:a;}
struct Segmenttree
{
	struct node
	{
		int l,r;
		ll v,lazy;
	}tree[maxn<<3];
	void build(int p,int l,int r)
	{
		tree[p].l=l;
		tree[p].r=r;
		if(l==r){tree[p].v=a[l];return;}
		int mid=l+r>>1;
		build(p<<1,l,mid);
		build(p<<1|1,mid+1,r);
		tree[p].v=Min(tree[p<<1].v,tree[p<<1|1].v);
	}
	inline void putdown(int p)
	{
		tree[p<<1].v+=tree[p].lazy;
		tree[p<<1|1].v+=tree[p].lazy;
		tree[p<<1].lazy+=tree[p].lazy;
		tree[p<<1|1].lazy+=tree[p].lazy;
		tree[p].lazy=0;
	}
	int query(int p)
	{
		if(tree[p].l==tree[p].r)return tree[p].l;
		int mid=tree[p].l+tree[p].r>>1;
		if(tree[p].lazy)putdown(p);
		if(tree[p<<1|1].v==0)return query(p<<1|1);
		else return query(p<<1);
	}
	void modify(int p,int x,int y,ll d)
	{
		if(x<=tree[p].l&&tree[p].r<=y)
		{
			tree[p].v+=d;
			tree[p].lazy+=d;
			return ;
		}
		int mid=tree[p].l+tree[p].r>>1;
		if(x<=mid&&y>=tree[p].l)modify(p<<1,x,y,d);
		if(y>mid&&x<=tree[p].r)modify(p<<1|1,x,y,d);
		tree[p].v=Min(tree[p<<1].v,tree[p<<1|1].v);
	}
}segmenttree;

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%I64d",&a[i]);
	segmenttree.build(1,1,n);
	for(int i=1;i<=n;i++)
	{
		int x=segmenttree.query(1);
		segmenttree.modify(1,x,x,inf);
		ans[x]=i;
		if(x<n)segmenttree.modify(1,x+1,n,-i);
	}
	for(int i=1;i<=n;i++)printf("%d ",ans[i]);
}


// luogu-judger-enable-o2
// Author -- Frame

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<iostream>

#define lowbit(x) ((x)&(-x))
#define Finline __inline__ __attribute__ ((always_inline))
#define DEBUG printf("Running on Line %d in Function %s\n",__LINE__,__FUNCTION__)

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;

const int inf=0x3f3f3f3f,Inf=0x7fffffff;
const ll INF=0x7fffffffffffffff;
const double eps=1e-8;

uint seed=19260817;
const uint _RAND_MAX_=4294967295u;
Finline uint Rand(){return seed=seed*998244353u+1000000007u;}

template <typename _Tp>_Tp gcd(const _Tp &a,const _Tp &b){return (!b)?a:gcd(b,a%b);}
template <typename _Tp>Finline _Tp abs(const _Tp &a){return a>0?a:-a;}
template <typename _Tp>Finline _Tp max(const _Tp &a,const _Tp &b){return a<b?b:a;}
template <typename _Tp>Finline _Tp min(const _Tp &a,const _Tp &b){return a<b?a:b;}
template <typename _Tp>Finline void chmax(_Tp &a,const _Tp &b){(a<b)&&(a=b);}
template <typename _Tp>Finline void chmin(_Tp &a,const _Tp &b){(a>b)&&(a=b);}
template <typename _Tp>Finline bool _cmp(const _Tp &a,const _Tp &b){return abs(a-b)<=eps;}
template <typename _Tp>Finline void read(_Tp& x)
{
    register char ch(getchar());
    bool f(false);
    while(ch<48||ch>57) f|=ch==45,ch=getchar();
    x=ch&15,ch=getchar();
    while(ch>=48&&ch<=57) x=(((x<<2)+x)<<1)+(ch&15),ch=getchar();
    if(f) x=-x;
}
template <typename _Tp,typename... Args>Finline void read(_Tp &t,Args &...args)
{
    read(t);read(args...);
}
Finline int read_str(char *s)
{
    register char ch(getchar());
    while(ch==' '||ch=='\r'||ch=='\n') ch=getchar();
    register char *tar=s;
    *tar=ch,ch=getchar();
    while(ch!=' '&&ch!='\r'&&ch!='\n'&&ch!=EOF) *(++tar)=ch,ch=getchar();
    return tar-s+1;
}

const int N=200005;
struct BIT{
	ll c[N];
	int n;
	Finline BIT(){n=200000;}
	Finline void add(int x,const ll &C){for(;x<=n;x+=lowbit(x))c[x]+=C;};
	Finline ll sum(int x){ll ans=0;for(;x;x-=lowbit(x))ans+=c[x];return ans;}
}tr;
ll a[N];
int b[N];
int _find(int l,int r,ll x)
{
	while(l<r)
	{
		int mid=(l+r+1)>>1;
		if(tr.sum(mid)<=x) l=mid;
		else r=mid-1;
	}
	return l;
}
int main()
{
	int n;
	read(n);
	for(int i=1;i<=n;++i) read(a[i]);
	for(int i=1;i<=n;++i)
	{
		tr.add(i+1,i);
	}
	for(int i=n;i>=1;--i)
	{
		b[i]=_find(1,n,a[i]);
		tr.add(b[i]+1,-b[i]);
	}
	for(int i=1;i<=n;++i) printf("%d ",b[i]);
	printf("\n");
    return 0;
}


// Author -- Frame

#pragma GCC optimize(2)

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<iostream>

#define lowbit(x) ((x)&(-x))
#define Finline __inline__ __attribute__ ((always_inline))
#define DEBUG printf("Running on Line %d in Function %s\n",__LINE__,__FUNCTION__)

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;

const int inf=0x3f3f3f3f,Inf=0x7fffffff;
const ll INF=0x7fffffffffffffff;
const double eps=1e-8;

uint seed=19260817;
const uint _RAND_MAX_=4294967295u;
Finline uint Rand(){return seed=seed*998244353u+1000000007u;}

template <typename _Tp>_Tp gcd(const _Tp &a,const _Tp &b){return (!b)?a:gcd(b,a%b);}
template <typename _Tp>Finline _Tp abs(const _Tp &a){return a>0?a:-a;}
template <typename _Tp>Finline _Tp max(const _Tp &a,const _Tp &b){return a<b?b:a;}
template <typename _Tp>Finline _Tp min(const _Tp &a,const _Tp &b){return a<b?a:b;}
template <typename _Tp>Finline void chmax(_Tp &a,const _Tp &b){(a<b)&&(a=b);}
template <typename _Tp>Finline void chmin(_Tp &a,const _Tp &b){(a>b)&&(a=b);}
template <typename _Tp>Finline bool _cmp(const _Tp &a,const _Tp &b){return abs(a-b)<=eps;}
template <typename _Tp>Finline void read(_Tp& x)
{
    register char ch(getchar());
    bool f(false);
    while(ch<48||ch>57) f|=ch==45,ch=getchar();
    x=ch&15,ch=getchar();
    while(ch>=48&&ch<=57) x=(((x<<2)+x)<<1)+(ch&15),ch=getchar();
    if(f) x=-x;
}
template <typename _Tp,typename... Args>Finline void read(_Tp &t,Args &...args)
{
    read(t);read(args...);
}
Finline int read_str(char *s)
{
    register char ch(getchar());
    while(ch==' '||ch=='\r'||ch=='\n') ch=getchar();
    register char *tar=s;
    *tar=ch,ch=getchar();
    while(ch!=' '&&ch!='\r'&&ch!='\n'&&ch!=EOF) *(++tar)=ch,ch=getchar();
    return tar-s+1;
}

const int N=200005;
struct Xor_base{
	ll a[63];
	bool Insert(ll x)
	{
		for(int i=60;i>=0;--i)
		{
			if((x>>i)&1)
			{
				if(a[i])
				{
					x^=a[i];
				}
				else
				{
					a[i]=x;
					return 1;
				}
			}
		}
		return 0;
	}
	ll Query()
	{
		ll ans=0;
		for(int i=50;i>=0;--i)
		{
			if((ans^a[i])>ans)
			{
				ans^=a[i];
			}
		}
		return ans;
	}
}bs;
struct BIT{
	ll c[N];
	int n;
	Finline BIT(){n=200000;}
	Finline void add(int x,const int &C){for(;x<=n;x+=lowbit(x))c[x]+=C;}
	Finline ll sum(int x){ll ans=0;for(;x;x-=lowbit(x))ans+=c[x];return ans;}
}tr;
int n;
ll t[N];
int _find(ll x)
{
	int l=1,r=n;
	while(l<r)
	{
		int mid=(l+r+1)>>1;
		if(tr.sum(mid)<=x) l=mid;
		else r=mid-1;
	}
	return l;
}
ll a[N];
int ans[N];
int main()
{
	bs.Insert(19260817);
	read(n);
	for(int i=1;i<=n;++i) read(a[i]);
	for(int i=1;i<=n;++i) t[i]=t[i-1]+i-1;
	for(int i=1;i<=n;++i)
	{
		tr.c[i]=t[i]-t[i^lowbit(i)];
	}
	for(int i=n;i>=1;--i)
	{
		int pos=_find(a[i]);
		ans[i]=pos;
		tr.add(pos+1,-pos);
	}
	for(int i=1;i<=n;++i) printf("%d ",ans[i]);
	printf("\n");
	t[0]=bs.Query();
    return 0;
}


// luogu-judger-enable-o2
// Author -- Frame

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<iostream>

#define lowbit(x) ((x)&(-x))
#define Finline __inline__ __attribute__ ((always_inline))
#define DEBUG printf("Running on Line %d in Function %s\n",__LINE__,__FUNCTION__)

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;

const int inf=0x3f3f3f3f,Inf=0x7fffffff;
const ll INF=0x7fffffffffffffff;
const double eps=1e-8;

uint seed=19260817;
const uint _RAND_MAX_=4294967295u;
Finline uint Rand(){return seed=seed*998244353u+1000000007u;}

template <typename _Tp>_Tp gcd(const _Tp &a,const _Tp &b){return (!b)?a:gcd(b,a%b);}
template <typename _Tp>Finline _Tp abs(const _Tp &a){return a>0?a:-a;}
template <typename _Tp>Finline _Tp max(const _Tp &a,const _Tp &b){return a<b?b:a;}
template <typename _Tp>Finline _Tp min(const _Tp &a,const _Tp &b){return a<b?a:b;}
template <typename _Tp>Finline void chmax(_Tp &a,const _Tp &b){(a<b)&&(a=b);}
template <typename _Tp>Finline void chmin(_Tp &a,const _Tp &b){(a>b)&&(a=b);}
template <typename _Tp>Finline bool _cmp(const _Tp &a,const _Tp &b){return abs(a-b)<=eps;}
template <typename _Tp>Finline void read(_Tp& x)
{
    register char ch(getchar());
    bool f(false);
    while(ch<48||ch>57) f|=ch==45,ch=getchar();
    x=ch&15,ch=getchar();
    while(ch>=48&&ch<=57) x=(((x<<2)+x)<<1)+(ch&15),ch=getchar();
    if(f) x=-x;
}
template <typename _Tp,typename... Args>Finline void read(_Tp &t,Args &...args)
{
    read(t);read(args...);
}
Finline int read_str(char *s)
{
    register char ch(getchar());
    while(ch==' '||ch=='\r'||ch=='\n') ch=getchar();
    register char *tar=s;
    *tar=ch,ch=getchar();
    while(ch!=' '&&ch!='\r'&&ch!='\n'&&ch!=EOF) *(++tar)=ch,ch=getchar();
    return tar-s+1;
}

const int N=200005;
struct seg_tr{
	struct Node{
		int ls,rs;
		ll minn,tag;
		int pos;
	}f[N<<1];
	int node_cnt;
	inline void PushUp(const int &x)
	{
		f[x].minn=f[f[x].rs].minn;
		f[x].pos=f[f[x].rs].pos;
		if(f[f[x].ls].minn<f[x].minn)
		{
			f[x].minn=f[f[x].ls].minn;
			f[x].pos=f[f[x].ls].pos;
		}
	}
	int build(const int &l,const int &r,ll *arr)
	{
		int cur=++node_cnt;
		if(l==r)
		{
			f[cur].minn=arr[l];
			f[cur].pos=l;
			return cur;
		}
		int mid=(l+r)>>1;
		f[cur].ls=build(l,mid,arr);
		f[cur].rs=build(mid+1,r,arr);
		PushUp(cur);
		return cur;
	}
	inline void add(const int &cur,const ll &val)
	{
		f[cur].minn+=val;
		f[cur].tag+=val;
	}
	inline void PushDown(const int &x)
	{
		if(f[x].tag)
		{
			add(f[x].ls,f[x].tag);
			add(f[x].rs,f[x].tag);
			f[x].tag=0;
		}
	}
	void Update(const int &L,const int &R,const int &l,const int &r,const int &cur,const ll &val)
	{
		if(L<=l&&r<=R)
		{
			add(cur,val);
			return;
		}
		int mid=(l+r)>>1;
		PushDown(cur);
		if(L<=mid) Update(L,R,l,mid,f[cur].ls,val);
		if(R>mid) Update(L,R,mid+1,r,f[cur].rs,val);
		PushUp(cur);
	}
	inline int Query(){return f[1].pos;}
}tr;
ll a[N];
int b[N];
int main()
{
	int n;
	read(n);
	for(int i=1;i<=n;++i) read(a[i]);
	int root=tr.build(1,n,a),tmp;
	for(int i=1;i<=n;++i)
	{
		b[tmp=tr.Query()]=i;
		tr.Update(tmp,n,1,n,root,-i);
		tr.Update(tmp,tmp,1,n,root,1e17);
	}
	for(int i=1;i<=n;++i) printf("%d ",b[i]);
	printf("\n");
    return 0;
}


// luogu-judger-enable-o2
// Author -- Frame

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<iostream>

#define lowbit(x) ((x)&(-x))
#define Finline __inline__ __attribute__ ((always_inline))
#define DEBUG printf("Running on Line %d in Function %s\n",__LINE__,__FUNCTION__)

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;

const int inf=0x3f3f3f3f,Inf=0x7fffffff;
const ll INF=0x7fffffffffffffff;
const double eps=1e-8;

uint seed=19260817;
const uint _RAND_MAX_=4294967295u;
Finline uint Rand(){return seed=seed*998244353u+1000000007u;}

template <typename _Tp>_Tp gcd(const _Tp &a,const _Tp &b){return (!b)?a:gcd(b,a%b);}
template <typename _Tp>Finline _Tp abs(const _Tp &a){return a>0?a:-a;}
template <typename _Tp>Finline _Tp max(const _Tp &a,const _Tp &b){return a<b?b:a;}
template <typename _Tp>Finline _Tp min(const _Tp &a,const _Tp &b){return a<b?a:b;}
template <typename _Tp>Finline void chmax(_Tp &a,const _Tp &b){(a<b)&&(a=b);}
template <typename _Tp>Finline void chmin(_Tp &a,const _Tp &b){(a>b)&&(a=b);}
template <typename _Tp>Finline bool _cmp(const _Tp &a,const _Tp &b){return abs(a-b)<=eps;}
template <typename _Tp>Finline void read(_Tp& x)
{
    register char ch(getchar());
    bool f(false);
    while(ch<48||ch>57) f|=ch==45,ch=getchar();
    x=ch&15,ch=getchar();
    while(ch>=48&&ch<=57) x=(((x<<2)+x)<<1)+(ch&15),ch=getchar();
    if(f) x=-x;
}
template <typename _Tp,typename... Args>Finline void read(_Tp &t,Args &...args)
{
    read(t);read(args...);
}
Finline int read_str(char *s)
{
    register char ch(getchar());
    while(ch==' '||ch=='\r'||ch=='\n') ch=getchar();
    register char *tar=s;
    *tar=ch,ch=getchar();
    while(ch!=' '&&ch!='\r'&&ch!='\n'&&ch!=EOF) *(++tar)=ch,ch=getchar();
    return tar-s+1;
}

const int N=200005;
struct seg_tr{
	struct Node{
		int ls,rs;
		ll minn,tag;
		int pos;
	}f[N<<1];
	int node_cnt;
	inline void PushUp(const int &x)
	{
		f[x].minn=f[f[x].rs].minn;
		f[x].pos=f[f[x].rs].pos;
		if(f[f[x].ls].minn<f[x].minn)
		{
			f[x].minn=f[f[x].ls].minn;
			f[x].pos=f[f[x].ls].pos;
		}
	}
	int build(const int &l,const int &r,ll *arr)
	{
		int cur=++node_cnt;
		if(l==r)
		{
			f[cur].minn=arr[l];
			f[cur].pos=l;
			return cur;
		}
		int mid=(l+r)>>1;
		f[cur].ls=build(l,mid,arr);
		f[cur].rs=build(mid+1,r,arr);
		PushUp(cur);
		return cur;
	}
	inline void add(const int &cur,const ll &val)
	{
		f[cur].minn+=val;
		f[cur].tag+=val;
	}
	inline void PushDown(const int &x)
	{
		if(f[x].tag)
		{
			add(f[x].ls,f[x].tag);
			add(f[x].rs,f[x].tag);
			f[x].tag=0;
		}
	}
	void Update(const int &L,const int &R,const int &l,const int &r,const int &cur,const int &val)
	{
		if(L<=l&&r<=R)
		{
			add(cur,val);
			return;
		}
		int mid=(l+r)>>1;
		PushDown(cur);
		if(L<=mid) Update(L,R,l,mid,f[cur].ls,val);
		if(R>mid) Update(L,R,mid+1,r,f[cur].rs,val);
		PushUp(cur);
	}
	inline int Query(){return f[1].pos;}
}tr;
ll a[N];
int b[N];
int main()
{
	int n;
	read(n);
	for(int i=1;i<=n;++i) read(a[i]);
	int root=tr.build(1,n,a),tmp;
	for(int i=1;i<=n;++i)
	{
		b[tmp=tr.Query()]=i;
		tr.Update(tmp,n,1,n,root,-i);
		tr.Update(tmp,tmp,1,n,root,1e17);
	}
	for(int i=1;i<=n;++i) printf("%d ",b[i]);
	printf("\n");
    return 0;
}


// luogu-judger-enable-o2
// Author -- Frame

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<iostream>

#define lowbit(x) ((x)&(-x))
#define Finline __inline__ __attribute__ ((always_inline))
#define DEBUG printf("Running on Line %d in Function %s\n",__LINE__,__FUNCTION__)

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;

const int inf=0x3f3f3f3f,Inf=0x7fffffff;
const ll INF=0x7fffffffffffffff;
const double eps=1e-8;

uint seed=19260817;
const uint _RAND_MAX_=4294967295u;
Finline uint Rand(){return seed=seed*998244353u+1000000007u;}

template <typename _Tp>_Tp gcd(const _Tp &a,const _Tp &b){return (!b)?a:gcd(b,a%b);}
template <typename _Tp>Finline _Tp abs(const _Tp &a){return a>0?a:-a;}
template <typename _Tp>Finline _Tp max(const _Tp &a,const _Tp &b){return a<b?b:a;}
template <typename _Tp>Finline _Tp min(const _Tp &a,const _Tp &b){return a<b?a:b;}
template <typename _Tp>Finline void chmax(_Tp &a,const _Tp &b){(a<b)&&(a=b);}
template <typename _Tp>Finline void chmin(_Tp &a,const _Tp &b){(a>b)&&(a=b);}
template <typename _Tp>Finline bool _cmp(const _Tp &a,const _Tp &b){return abs(a-b)<=eps;}
template <typename _Tp>Finline void read(_Tp& x)
{
    register char ch(getchar());
    bool f(false);
    while(ch<48||ch>57) f|=ch==45,ch=getchar();
    x=ch&15,ch=getchar();
    while(ch>=48&&ch<=57) x=(((x<<2)+x)<<1)+(ch&15),ch=getchar();
    if(f) x=-x;
}
template <typename _Tp,typename... Args>Finline void read(_Tp &t,Args &...args)
{
    read(t);read(args...);
}
Finline int read_str(char *s)
{
    register char ch(getchar());
    while(ch==' '||ch=='\r'||ch=='\n') ch=getchar();
    register char *tar=s;
    *tar=ch,ch=getchar();
    while(ch!=' '&&ch!='\r'&&ch!='\n'&&ch!=EOF) *(++tar)=ch,ch=getchar();
    return tar-s+1;
}

const int N=200005;
struct seg_tr{
	struct Node{
		int ls,rs;
		int minn,tag,pos;
	}f[N<<1];
	int node_cnt;
	inline void PushUp(const int &x)
	{
		f[x].minn=f[f[x].rs].minn;
		f[x].pos=f[f[x].rs].pos;
		if(f[f[x].ls].minn<f[x].minn)
		{
			f[x].minn=f[f[x].ls].minn;
			f[x].pos=f[f[x].ls].pos;
		}
	}
	int build(const int &l,const int &r,int *arr)
	{
		int cur=++node_cnt;
		if(l==r)
		{
			f[cur].minn=arr[l];
			f[cur].pos=l;
			return cur;
		}
		int mid=(l+r)>>1;
		f[cur].ls=build(l,mid,arr);
		f[cur].rs=build(mid+1,r,arr);
		PushUp(cur);
		return cur;
	}
	inline void add(const int &cur,const int &val)
	{
		f[cur].minn+=val;
		f[cur].tag+=val;
	}
	inline void PushDown(const int &x)
	{
		if(f[x].tag)
		{
			add(f[x].ls,f[x].tag);
			add(f[x].rs,f[x].tag);
			f[x].tag=0;
		}
	}
	void Update(const int &L,const int &R,const int &l,const int &r,const int &cur,const int &val)
	{
		if(L<=l&&r<=R)
		{
			add(cur,val);
			return;
		}
		int mid=(l+r)>>1;
		PushDown(cur);
		if(L<=mid) Update(L,R,l,mid,f[cur].ls,val);
		if(R>mid) Update(L,R,mid+1,r,f[cur].rs,val);
		PushUp(cur);
	}
	inline int Query(){return f[1].pos;}
}tr;
int a[N],b[N];
int main()
{
	int n;
	read(n);
	for(int i=1;i<=n;++i) read(a[i]);
	int root=tr.build(1,n,a),tmp;
	for(int i=1;i<=n;++i)
	{
		b[tmp=tr.Query()]=i;
		tr.Update(tmp,n,1,n,root,-i);
		tr.Update(tmp,tmp,1,n,root,inf);
	}
	for(int i=1;i<=n;++i) printf("%d ",b[i]);
	printf("\n");
    return 0;
}


// luogu-judger-enable-o2
// Author -- Frame

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<iostream>

#define lowbit(x) ((x)&(-x))
#define Finline __inline__ __attribute__ ((always_inline))
#define DEBUG printf("Running on Line %d in Function %s\n",__LINE__,__FUNCTION__)

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;

const int inf=0x3f3f3f3f,Inf=0x7fffffff;
const ll INF=0x7fffffffffffffff;
const double eps=1e-8;

uint seed=19260817;
const uint _RAND_MAX_=4294967295u;
Finline uint Rand(){return seed=seed*998244353u+1000000007u;}

template <typename _Tp>_Tp gcd(const _Tp &a,const _Tp &b){return (!b)?a:gcd(b,a%b);}
template <typename _Tp>Finline _Tp abs(const _Tp &a){return a>0?a:-a;}
template <typename _Tp>Finline _Tp max(const _Tp &a,const _Tp &b){return a<b?b:a;}
template <typename _Tp>Finline _Tp min(const _Tp &a,const _Tp &b){return a<b?a:b;}
template <typename _Tp>Finline void chmax(_Tp &a,const _Tp &b){(a<b)&&(a=b);}
template <typename _Tp>Finline void chmin(_Tp &a,const _Tp &b){(a>b)&&(a=b);}
template <typename _Tp>Finline bool _cmp(const _Tp &a,const _Tp &b){return abs(a-b)<=eps;}
template <typename _Tp>Finline void read(_Tp& x)
{
    register char ch(getchar());
    bool f(false);
    while(ch<48||ch>57) f|=ch==45,ch=getchar();
    x=ch&15,ch=getchar();
    while(ch>=48&&ch<=57) x=(((x<<2)+x)<<1)+(ch&15),ch=getchar();
    if(f) x=-x;
}
template <typename _Tp,typename... Args>Finline void read(_Tp &t,Args &...args)
{
    read(t);read(args...);
}
Finline int read_str(char *s)
{
    register char ch(getchar());
    while(ch==' '||ch=='\r'||ch=='\n') ch=getchar();
    register char *tar=s;
    *tar=ch,ch=getchar();
    while(ch!=' '&&ch!='\r'&&ch!='\n'&&ch!=EOF) *(++tar)=ch,ch=getchar();
    return tar-s+1;
}

const int N=200005;
struct seg_tr{
	struct Node{
		int ls,rs;
		ll minn,tag;
		int pos;
	}f[N<<1];
	int node_cnt;
	inline void PushUp(const int &x)
	{
		f[x].minn=f[f[x].rs].minn;
		f[x].pos=f[f[x].rs].pos;
		if(f[f[x].ls].minn<f[x].minn)
		{
			f[x].minn=f[f[x].ls].minn;
			f[x].pos=f[f[x].ls].pos;
		}
	}
	int build(const int &l,const int &r,ll *arr)
	{
		int cur=++node_cnt;
		if(l==r)
		{
			f[cur].minn=arr[l];
			f[cur].pos=l;
			return cur;
		}
		int mid=(l+r)>>1;
		f[cur].ls=build(l,mid,arr);
		f[cur].rs=build(mid+1,r,arr);
		PushUp(cur);
		return cur;
	}
	inline void add(const int &cur,const ll &val)
	{
		f[cur].minn+=val;
		f[cur].tag+=val;
	}
	inline void PushDown(const int &x)
	{
		if(f[x].tag)
		{
			add(f[x].ls,f[x].tag);
			add(f[x].rs,f[x].tag);
			f[x].tag=0;
		}
	}
	void Update(const int &L,const int &R,const int &l,const int &r,const int &cur,const int &val)
	{
		if(L<=l&&r<=R)
		{
			add(cur,val);
			return;
		}
		int mid=(l+r)>>1;
		PushDown(cur);
		if(L<=mid) Update(L,R,l,mid,f[cur].ls,val);
		if(R>mid) Update(L,R,mid+1,r,f[cur].rs,val);
		PushUp(cur);
	}
	inline int Query(){return f[1].pos;}
}tr;
ll a[N];
int b[N];
int main()
{
	int n;
	read(n);
	for(int i=1;i<=n;++i) read(a[i]);
	int root=tr.build(1,n,a),tmp;
	for(int i=1;i<=n;++i)
	{
		b[tmp=tr.Query()]=i;
		tr.Update(tmp,n,1,n,root,-i);
		tr.Update(tmp,tmp,1,n,root,inf);
	}
	for(int i=1;i<=n;++i) printf("%d ",b[i]);
	printf("\n");
    return 0;
}


#include <bits/stdc++.h>
#define endl '\n'
#define debug(X) cout << #X << " = " << X << endl
#define SZ(X) ((int)X.size())

using namespace std;

const int MN = 200010;

long long a[MN];

bool cmp(int i, int j) {
	if (a[i] != a[j]) return a[i] < a[j];
	return i > j;
}

int main() {
	ios_base::sync_with_stdio(false); cin.tie(0);
	#ifdef UTP
	freopen("input.txt", "r", stdin);
	#endif
	int n; cin >> n;
	for (int i = 0; i < n; i++) cin >> a[i];
	vector<int> order(n);
	for (int i = 0; i < n; i++) order[i] = i;
	sort(order.begin(), order.end(), cmp);
	vector<int> ans(n);
	for (int i = 0; i < n; i++)
		ans[order[i]] = i;
	for (int i = 0; i < n; i++)
		cout << ans[i] + 1 << " ";
	cout << endl;
	return 0;
}


#include <bits/stdc++.h>
#define endl '\n'
#define debug(X) cout << #X << " = " << X << endl
#define SZ(X) ((int)X.size())

using namespace std;

long long f(long long x) { return (x * (x + 1)) / 2; }

int main() {
	ios_base::sync_with_stdio(false); cin.tie(0);
	#ifdef UTP
	freopen("input.txt", "r", stdin);
	#endif
	int n; cin >> n;
	map< long long, stack<int> > mapper;
	for (int i = 0; i < n; i++) {
		long long x; cin >> x;
		mapper[x].push(i);
	}
	vector<int> ans(n);
	for (int i = 0; i < n; i++) {
		int c = f(i);
		auto it = mapper.upper_bound(c); it--;
		stack<int> &st = (*it).second;
		int pos = st.top(); st.pop();
		ans[pos] = i;
	}
	for (int i = 0; i < n; i++)
		cout << ans[i] + 1 << " ";
	cout << endl;
	return 0;
}


#include <bits/stdc++.h>
#define endl '\n'
#define debug(X) cout << #X << " = " << X << endl
#define SZ(X) ((int)X.size())

using namespace std;

long long f(long long x) { return (x * (x + 1)) / 2; }

int main() {
	ios_base::sync_with_stdio(false); cin.tie(0);
	#ifdef UTP
	freopen("input.txt", "r", stdin);
	#endif
	int n; cin >> n;
	map< long long, stack<int> > mapper;
	for (int i = 0; i < n; i++) {
		long long x; cin >> x;
		mapper[x].push(i);
	}
	vector<int> ans(n);
	for (int i = 0; i < n; i++) {
		long long c = f(i);
		auto it = mapper.upper_bound(c); it--;
		stack<int> &st = (*it).second;
		int pos = st.top(); st.pop();
		ans[pos] = i;
		if (SZ(st) == 0) mapper.erase(it);
	}
	for (int i = 0; i < n; i++)
		cout << ans[i] + 1 << " ";
	cout << endl;
	return 0;
}


#include <bits/stdc++.h>
#define endl '\n'
#define debug(X) cout << #X << " = " << X << endl

using namespace std;

const int MN = 200010;

int n;
long long ft[MN];

void update(int pos, long long by) {
	while (pos < n) ft[pos] += by, pos |= pos + 1;
}

long long query(int pos) {
	long long ans = 0;
	while (pos >= 0) ans += ft[pos], pos = (pos & (pos + 1)) - 1;
	return ans;
}

int main() {
	ios_base::sync_with_stdio(false); cin.tie(0);
	#ifdef UTP
	freopen("input.txt", "r", stdin);
	#endif
	cin >> n;
	vector<long long> a(n);
	for (int i = 0; i < n; i++)
		cin >> a[i];
	for (int i = 0; i < n; i++)
		update(i, i);
	vector<int> ans(n);
	for (int i = n - 1; i >= 0; i--) {
		int lo = 0, hi = n;
		while (hi - lo > 1) {
			int mi = (hi + lo) / 2;
			if (query(mi) <= a[i]) lo = mi;
			else hi = mi;
		}
		update(lo + 1, -lo - 1);
		ans[i] = lo;
	}
	for (int i = 0; i < n; i++)
		cout << ans[i] + 1 << " ";
	cout << endl;
	return 0;
}


#include <bits/stdc++.h>
#define endl '\n'
#define debug(X) cout << #X << " = " << X << endl
#define SZ(X) ((int)X.size())

using namespace std;

long long f(long long x) { return (x * (x + 1)) / 2; }

int main() {
	ios_base::sync_with_stdio(false); cin.tie(0);
	#ifdef UTP
	freopen("input.txt", "r", stdin);
	#endif
	int n; cin >> n;
	map< long long, stack<int> > mapper;
	for (int i = 0; i < n; i++) {
		long long x; cin >> x;
		mapper[x].push(i);
	}
	vector<int> ans(n);
	for (int i = 0; i < n; i++) {
		int c = f(i);
		auto it = mapper.upper_bound(c); it--;
		stack<int> &st = (*it).second;
		int pos = st.top(); st.pop();
		ans[pos] = i;
		if (SZ(st) == 0) mapper.erase(it);
	}
	for (int i = 0; i < n; i++)
		cout << ans[i] + 1 << " ";
	cout << endl;
	return 0;
}


#include<cstdio>
#define tp T[p]
typedef long long ll;
const int N=200010;
int n,a[N],v[N]; ll s[N];
struct node { int L,R,mid; ll sum; }T[N<<2];
void build(int l,int r,int p) {
	tp=(node){l,r,(l+r>>1),0};
	if (l==r) { tp.sum=l; return ; }
	build(l,tp.mid,p<<1);
	build(tp.mid+1,r,p<<1|1);
	tp.sum=T[p<<1].sum+T[p<<1|1].sum;
}
ll query(int l,int r,int p) {
	if (tp.L==l&&tp.R==r) return tp.sum;
	if (r<=tp.mid) return query(l,r,p<<1);
	if (l>tp.mid) return query(l,r,p<<1|1);
	return query(l,tp.mid,p<<1)+query(tp.mid+1,r,p<<1|1);
}
void update(int i,int p) {
	if (tp.L==tp.R) { tp.sum=0; return ; }
	update(i,p<<1|(i>tp.mid));
	tp.sum=T[p<<1].sum+T[p<<1|1].sum;
}

int main() {
	scanf("%d",&n); build(1,n,1);
	for (int i=1; i<=n; ++i) scanf("%lld",s+i);
	for (int i=n; i; --i) {
		int l=1,r=n;
		while (l<r) {
			int mid=(l+r>>1),t=query(1,mid,1);
			if (t>s[i]) r=mid; else l=mid+1;
		}
		while (v[r]) --r; v[r]=1;
		a[i]=r; update(r,1);
	}
	for (int i=1; i<=n; ++i) printf("%d ",a[i]);
	return 0;
}


#include<cstdio>
#include<cmath>
#define lb(x) (-x&x)
typedef long long ll;
const int N=200010; int n,hb,x[N]; ll a[N],c[N];

inline void upd(int i,int x) { for ( ; i<=n; i+=lb(i)) c[i]+=x; }
inline int qry(ll x) {
	int t=0; ll s=0;
	for (int i=hb; i; i>>=1)
		if (t+i<=n&&s+c[t+i]<=x) { t+=i; s+=c[t]; }
	return t+1;
}
int main() {
	scanf("%d",&n); hb=(1<<(int)log2(n));
	for (int i=1; i<=n; ++i) { scanf("%lld",a+i); upd(i,i); }
	for (int i=n; i; --i) { x[i]=qry(a[i]); upd(x[i],-x[i]); }
	for (int i=1; i<=n; ++i) printf("%d ",x[i]);
	return 0;
}


#include<cstdio>
#include<cctype>
#define getc (l==r&&(r=(l=c)+fread(c,1,1<<21,stdin),l==r)?EOF:*l++)
#define tp T[p]
typedef long long ll;
char c[1<<21],*l=c,*r=c;
inline ll read() {
	ll x=0; char ch=getc;
	while (!isdigit(ch)) ch=getc;
	while (isdigit(ch)) { x=x*10+(ch^48); ch=getc; }
	return x;
}

const int N=200010;
int n,a[N],v[N],pre[N],nxt[N]; ll s[N],f[N];
inline int lb(int x) { return (-x&x); }
inline int query(int x) { ll t=0; for ( ; x; x-=lb(x)) t+=f[x]; return t; }
inline void update(int i,int x) { for ( ; i<=n; i+=lb(i)) f[i]+=x; }

int main() {
	n=read();
	for (int i=1; i<=n; ++i) {
		s[i]=read(); update(i,i);
		nxt[i]=i+1; pre[i]=i-1;
	}
	for (int i=n; i; --i) {
		int l=1,r=n;
		while (l<r) {
			int mid=(l+r>>1),t=query(mid);
			if (t>s[i]) r=mid; else l=mid+1;
		}
		if (!v[r]) v[r]=1;
		else { r=pre[r]; nxt[r]=nxt[nxt[r]]; pre[nxt[r]]=r; }
		a[i]=r; update(r,-r);
	}
	for (int i=1; i<=n; ++i) printf("%d ",a[i]);
	return 0;
}


#include<cstdio>
#include<cctype>
#define getc (l==r&&(r=(l=c)+fread(c,1,1<<21,stdin),l==r)?EOF:*l++)
#define tp T[p]
typedef long long ll;
char c[1<<21],*l=c,*r=c;
inline ll read() {
	ll x=0; char ch=getc;
	while (!isdigit(ch)) ch=getc;
	while (isdigit(ch)) { x=x*10+(ch^48); ch=getc; }
	return x;
}

const int N=200010;
int n,a[N],v[N],pre[N],nxt[N]; ll s[N],f[N];
inline int lb(int x) { return (-x&x); }
inline ll query(int x) { ll t=0; for ( ; x; x-=lb(x)) t+=f[x]; return t; }
inline void update(int i,int x) { for ( ; i<=n; i+=lb(i)) f[i]+=x; }

int main() {
	n=read();
	for (int i=1; i<=n; ++i) {
		s[i]=read(); update(i,i);
		nxt[i]=i+1; pre[i]=i-1;
	}
	for (int i=n; i; --i) {
		int l=1,r=n;
		while (l<r) {
			int mid=(l+r>>1),t=query(mid);
			if (t>s[i]) r=mid; else l=mid+1;
		}
		if (v[r]) r=pre[r];
		else { v[r]=1; pre[nxt[r]]=pre[r]; nxt[pre[r]]=nxt[r]; }
		a[i]=r; update(r,-r);
	}
	for (int i=1; i<=n; ++i) printf("%d ",a[i]);
	return 0;
}


#include<cstdio>
#include<cctype>
#define getc (l==r&&(r=(l=c)+fread(c,1,1<<21,stdin),l==r)?EOF:*l++)
#define tp T[p]
typedef long long ll;
char c[1<<21],*l=c,*r=c;
inline ll read() {
	ll x=0; char ch=getc;
	while (!isdigit(ch)) ch=getc;
	while (isdigit(ch)) { x=x*10+(ch^48); ch=getc; }
	return x;
}

const int N=200010;
int n,a[N],v[N]; ll s[N],f[N];
inline int lb(int x) { return (-x&x); }
inline int query(int x) { ll t=0; for ( ; x; x-=lb(x)) t+=f[x]; return t; }
inline void update(int i,int x) { for ( ; i<=n; i+=lb(i)) f[i]+=x; }

int main() {
	n=read();
	for (int i=1; i<=n; ++i) s[i]=read(),update(i,i);
	for (int i=n; i; --i) {
		int l=1,r=n;
		while (l<r) {
			int mid=(l+r>>1),t=query(mid);
			if (t>s[i]) r=mid; else l=mid+1;
		}
		while (v[r]) --r; v[r]=1;
		a[i]=r; update(r,-r);
	}
	for (int i=1; i<=n; ++i) printf("%d ",a[i]);
	return 0;
}


#include<cstdio>
#include<cmath>
#define lb(x) (-x&x)
typedef long long ll;
const int N=200010; int n,hb,x[N]; ll a[N],c[N];

inline void upd(int i,int x) { for ( ; i<=n; i+=lb(i)) c[i]+=x; }
inline int qry(ll x) {
	int t=0; ll s=0;
	for (int i=hb; i; i>>=1)
		if (t+i<=n&&s+c[t+i]<=x) { t+=i; s+=c[t]; }
	return t+1;
}
int main() {
	scanf("%d",&n); hb=(1<<(int)log2(n));
	for (int i=1; i<=n; ++i) { scanf("%lld",a+i); upd(i,i); }
	for (int i=n; i; --i) { x[i]=qry(x[i]); upd(x[i],-x[i]); }
	for (int i=1; i<=n; ++i) printf("%d ",x[i]);
	return 0;
}


#include<cstdio>
#include<cctype>
#define getc (l==r&&(r=(l=c)+fread(c,1,1<<21,stdin),l==r)?EOF:*l++)
#define tp T[p]
typedef long long ll;
char c[1<<21],*l=c,*r=c;
inline ll read() {
	ll x=0; char ch=getc;
	while (!isdigit(ch)) ch=getc;
	while (isdigit(ch)) { x=x*10+(ch^48); ch=getc; }
	return x;
}

const int N=200010;
int n,a[N],v[N],pre[N],nxt[N]; ll s[N],f[N];
inline int lb(int x) { return (-x&x); }
inline int query(int x) { ll t=0; for ( ; x; x-=lb(x)) t+=f[x]; return t; }
inline void update(int i,int x) { for ( ; i<=n; i+=lb(i)) f[i]+=x; }

int main() {
	n=read();
	for (int i=1; i<=n; ++i) {
		s[i]=read(); update(i,i);
		nxt[i]=i+1; pre[i]=i-1;
	}
	for (int i=n; i; --i) {
		int l=1,r=n;
		while (l<r) {
			int mid=(l+r>>1),t=query(mid);
			if (t>s[i]) r=mid; else l=mid+1;
		}
		if (v[r]) r=pre[r];
		else { v[r]=1; pre[nxt[r]]=pre[r]; nxt[pre[r]]=nxt[r]; }
		a[i]=r; update(r,-r);
	}
	for (int i=1; i<=n; ++i) printf("%d ",a[i]);
	return 0;
}


#include<cstdio>
#include<cctype>
#define getc (l==r&&(r=(l=c)+fread(c,1,1<<21,stdin),l==r)?EOF:*l++)
#define tp T[p]
typedef long long ll;
char c[1<<21],*l=c,*r=c;
inline ll read() {
	ll x=0; char ch=getc;
	while (!isdigit(ch)) ch=getc;
	while (isdigit(ch)) { x=x*10+(ch^48); ch=getc; }
	return x;
}

const int N=200010;
int n,a[N],v[N],pre[N],nxt[N]; ll s[N],f[N];
inline int lb(int x) { return (-x&x); }
inline int query(int x) { ll t=0; for ( ; x; x-=lb(x)) t+=f[x]; return t; }
inline void update(int i,int x) { for ( ; i<=n; i+=lb(i)) f[i]+=x; }

int main() {
	n=read();
	for (int i=1; i<=n; ++i) {
		s[i]=read(); update(i,i);
		nxt[i]=i+1; pre[i]=i-1;
	}
	for (int i=n; i; --i) {
		int l=1,r=n;
		while (l<r) {
			int mid=(l+r>>1),t=query(mid);
			if (t==s[i]) { r=mid; break; }
			if (t>s[i]) r=mid; else l=mid+1;
		}
		if (v[r]) r=pre[r];
		else { v[r]=1; pre[nxt[r]]=pre[r]; nxt[pre[r]]=nxt[r]; }
		a[i]=r; update(r,-r);
	}
	for (int i=1; i<=n; ++i) printf("%d ",a[i]);
	return 0;
}


#include<cstdio>
#include<cctype>
#define getc (l==r&&(r=(l=c)+fread(c,1,1<<21,stdin),l==r)?EOF:*l++)
#define tp T[p]
typedef long long ll;
char c[1<<21],*l=c,*r=c;
inline ll read() {
	ll x=0; char ch=getc;
	while (!isdigit(ch)) ch=getc;
	while (isdigit(ch)) { x=x*10+(ch^48); ch=getc; }
	return x;
}

const int N=200010;
int n,a[N],v[N],pre[N],nxt[N]; ll s[N],f[N];
inline int lb(int x) { return (-x&x); }
inline int query(int x) { ll t=0; for ( ; x; x-=lb(x)) t+=f[x]; return t; }
inline void update(int i,int x) { for ( ; i<=n; i+=lb(i)) f[i]+=x; }

int main() {
	n=read();
	for (int i=1; i<=n; ++i) {
		s[i]=read(); update(i,i);
		nxt[i]=i+1; pre[i]=i-1;
	}
	for (int i=n; i; --i) {
		int l=1,r=n;
		while (l<r) {
			int mid=(l+r>>1),t=query(mid);
			if (mid==s[i]) { r=mid; break; }
			if (t>s[i]) r=mid; else l=mid+1;
		}
		if (v[r]) r=pre[r];
		else { v[r]=1; pre[nxt[r]]=pre[r]; nxt[pre[r]]=nxt[r]; }
		a[i]=r; update(r,-r);
	}
	for (int i=1; i<=n; ++i) printf("%d ",a[i]);
	return 0;
}


#pragma GCC optimize ("Ofast")
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
//#include<ext/pb_ds/assoc_container.hpp>
//#include<ext/pb_ds/tree_policy.hpp>
#define INF 2147483647
#define LLINF LLONG_MAX
#define PI 3.1415926535
#define MOD 1000000007
#define MOD2 998244353
#define SP << ' '
#define EL << '\n'
#define FL << flush
#define sqr(x) ((x)*(x))
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define distinct(x) sort(all(x)); x.resize(unique(all(x))-x.begin());
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define FOR(i,l,r) for (int i = l; i < r; i++)
#define FORD(i,r,l) for (int i = r; i > l; i--)
using namespace std;
//using namespace __gnu_pbds;
//mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//mt19937_64 rng64(chrono::steady_clock::now().time_since_epoch().count());
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
//typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> bst;
namespace input {
	template<class T> inline void _R(T &x) {cin >> x;}
	inline void R() {}
	template<class T1, class... T2> inline void R(T1 &x, T2 &...y) { _R(x); R(y...);}
} using namespace input;
namespace overload_output {
	template<class T1, class T2> inline ostream& operator << (ostream& out, pair<T1,T2>& p) {return out << p.first << ' ' << p.second;}
	template<class T> inline ostream& operator << (ostream& out, vector<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, deque<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, forward_list<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, list<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, set<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, multiset<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, unordered_set<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, unordered_multiset<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, map<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, multimap<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, unordered_map<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, unordered_multimap<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
} using namespace overload_output;
namespace output {
	template<class T> inline void _W(const T& x) {cout << x;}
	template<class T1, class T2> inline void _W(const pair<T1,T2>& p) {_W(p.first); _W(' '); _W(p.second);}
	template<class T> inline void _W(const vector<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const deque<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const forward_list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2, class T3> inline void _W(const set<T1,T2,T3>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const unordered_set<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const unordered_multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const map<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const unordered_map<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const unordered_multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}

 	inline void W() {cout << '\n';}
	template<class T> inline void W(const T &x) {_W(x); W();}
	template<class T1, class... T2> inline void W(const T1 &x, const T2 &...y) { _W(x); _W(' '); W(y...);}
} using namespace output;

int main() {
	int n; R(n);
	vector<int> v(n); for (auto& i : v) R(i);

	list<int> ls;
	ls.pb(1);
	for (int i = 1; i < n; i++) {
		auto it = ls.begin();
		int cur = 0;
		for (int j = 0; j <= i; j++) {
			if (cur == v[i]) {ls.insert(it,i+1); break;}
			if (*it <= i) cur += *it;
			it++;
		}
	}

	W(ls);

	return 0;
}

static auto _batch_ios = [](){
	#ifndef LOCAL
	ios::sync_with_stdio(false);
	cin.tie(0);
	#endif
	cout << fixed << setprecision(12);
	return 42;
}();


#pragma GCC optimize ("Ofast")
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
//#include<ext/pb_ds/assoc_container.hpp>
//#include<ext/pb_ds/tree_policy.hpp>
#define INF 2147483647
#define LLINF LLONG_MAX
#define PI 3.1415926535
#define MOD 1000000007
#define MOD2 998244353
#define SP << ' '
#define EL << '\n'
#define FL << flush
#define sqr(x) ((x)*(x))
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define distinct(x) sort(all(x)); x.resize(unique(all(x))-x.begin());
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define FOR(i,l,r) for (int i = l; i < r; i++)
#define FORD(i,r,l) for (int i = r; i > l; i--)
using namespace std;
//using namespace __gnu_pbds;
//mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//mt19937_64 rng64(chrono::steady_clock::now().time_since_epoch().count());
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
//typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> bst;
namespace input {
	template<class T> inline void _R(T &x) {cin >> x;}
	inline void R() {}
	template<class T1, class... T2> inline void R(T1 &x, T2 &...y) { _R(x); R(y...);}
} using namespace input;
namespace overload_output {
	template<class T1, class T2> inline ostream& operator << (ostream& out, pair<T1,T2>& p) {return out << p.first << ' ' << p.second;}
	template<class T> inline ostream& operator << (ostream& out, vector<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, deque<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, forward_list<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, list<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, set<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, multiset<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, unordered_set<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, unordered_multiset<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, map<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, multimap<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, unordered_map<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, unordered_multimap<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
} using namespace overload_output;
namespace output {
	template<class T> inline void _W(const T& x) {cout << x;}
	template<class T1, class T2> inline void _W(const pair<T1,T2>& p) {_W(p.first); _W(' '); _W(p.second);}
	template<class T> inline void _W(const vector<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const deque<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const forward_list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2, class T3> inline void _W(const set<T1,T2,T3>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const unordered_set<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const unordered_multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const map<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const unordered_map<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const unordered_multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}

 	inline void W() {cout << '\n';}
	template<class T> inline void W(const T &x) {_W(x); W();}
	template<class T1, class... T2> inline void W(const T1 &x, const T2 &...y) { _W(x); _W(' '); W(y...);}
} using namespace output;

template<class T>
struct segment_tree{
	private:
	struct _node {
		int _val = 0;
		int _idx = 0;
		int _lazy = 0;
	} nullNode;

	vector<_node> _segtree;
	int _leaf_size = 0;

	inline int lchild (int id) {return id<<1;}
	inline int rchild (int id) {return (id<<1)+1;}

	inline _node __merge(_node a, _node b) {
		_node temp;
		if (a._val < b._val) {
			temp._idx = a._idx;
			temp._val = a._val;
		} else {
			temp._idx = b._idx;
			temp._val = b._val;
		}
		return temp;
	}

	inline void __init(int id, T val, int l, int r) {
		_segtree[id]._val = val;
		_segtree[id]._idx = l;
	}

	inline void __upd(int id, int val, int l, int r) {
		_segtree[id]._val += val;
		if (l == r) {
			_segtree[id]._idx = l;
			return;
		}
		auto a = _segtree[lchild(id)];
		auto b = _segtree[rchild(id)];
		if (a._val < b._val)
			_segtree[id]._idx = a._idx;
		else
			_segtree[id]._idx = b._idx;
	}

	inline void __lazy_upd(int id, int newtag, int l, int r) {
		_segtree[id]._lazy += newtag;
	}

	inline __pushdown(int id, int l, int r) {
		int mid = (l+r)>>1;
		__upd(lchild(id),_segtree[id]._lazy,l,mid);
		__upd(rchild(id),_segtree[id]._lazy,mid+1,r);
		__lazy_upd(lchild(id),_segtree[id]._lazy,l,mid);
		__lazy_upd(rchild(id),_segtree[id]._lazy,mid+1,r);
	}

 	inline void update(int id, int l, int r, int ql, int qr, int val) {
		if (qr < l || r < ql) return;
		if (_segtree[id]._lazy != nullNode._lazy) {
			if (l < r) __pushdown(id,l,r);
			_segtree[id]._lazy = nullNode._lazy;
		}
		if (ql <= l && r <= qr) {
			__upd(id,val,l,r);
			__lazy_upd(_segtree[id]._lazy,val,l,r);
			return;
		}
		int mid = (l+r)>>1;
		update(lchild(id),l,mid,ql,qr,val);
		update(rchild(id),mid+1,r,ql,qr,val);
		_segtree[id] = __merge(_segtree[lchild(id)],_segtree[rchild(id)]);
	}

	inline void update(int id, int l, int r, int q, int val) {
		if (_segtree[id]._lazy != nullNode._lazy) {
			if (l < r) __pushdown(id,l,r);
			_segtree[id]._lazy = nullNode._lazy;
		}
		if (l == r) {
			__upd(id,val,l,r);
			return;
		}
		int mid = (l+r)>>1;
		if (q <= mid)
			update(lchild(id),l,mid,q,val);
		else
			update(rchild(id),mid+1,r,q,val);
		_segtree[id] = __merge(_segtree[lchild(id)],_segtree[rchild(id)]);
	}

	inline _node query(int id, int l, int r, int ql, int qr) {
		if (qr < l || r < ql) return nullNode;
		if (_segtree[id]._lazy != nullNode._lazy) {
			if (l < r) __pushdown(id,l,r);
			_segtree[id]._lazy = nullNode._lazy;
		}
		if (ql <= l && r <= qr) return _segtree[id];
		int mid = (l+r)>>1;
		return __merge(query(id*2,l,mid,ql,qr),query(id*2+1,mid+1,r,ql,qr));
	}

	inline void build(int id, int l, int r, vector<T>& v) {
		if (l == r) {
			__init(id,v[l],l,r);
			return;
		}
		int mid = (l+r)/2;
		build(id*2,l,mid,v);
		build(id*2+1,mid+1,r,v);
		_segtree[id] = __merge(_segtree[id*2],_segtree[id*2+1]);
	}

	public:
	inline void update(int ql, int qr, int val) {
		update(1,0,_leaf_size-1,ql,qr,val);
	}

	inline _node query(int ql, int qr) {
		return query(1,0,_leaf_size-1,ql,qr);
	}

	inline segment_tree(vector<T>& v) {
		_segtree.resize(1 << __lg(v.size()-1)+2);
		_leaf_size = v.size();
		build(1,0,v.size()-1,v);
	}

	inline segment_tree(int size) {
		_segtree.resize(1 << __lg(size-1)+2, nullNode);
		_leaf_size = size;
	}
};
int main() {
	int n; R(n);
	vector<int> v(n); for (auto& i : v) R(i);

	segment_tree<int> st(v);

	vector<int> ans(n);
	for (int i = 1; i <= n; i++) {
		int idx = st.query(0,n-1)._idx;
		ans[idx] = i;
		st.update(idx+1,n-1,-i);
		st.update(idx,idx,1e9);
	}

	W(ans);

 	return 0;
}

static auto _batch_ios = [](){
	#ifndef LOCAL
	ios::sync_with_stdio(false);
	cin.tie(0);
	#endif
	cout << fixed << setprecision(12);
	return 42;
}();


#pragma GCC optimize ("Ofast")
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
//#include<ext/pb_ds/assoc_container.hpp>
//#include<ext/pb_ds/tree_policy.hpp>
#define INF 2147483647
#define LLINF LLONG_MAX
#define PI 3.1415926535
#define MOD 1000000007
#define MOD2 998244353
#define SP << ' '
#define EL << '\n'
#define FL << flush
#define sqr(x) ((x)*(x))
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define distinct(x) sort(all(x)); x.resize(unique(all(x))-x.begin());
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define FOR(i,l,r) for (int i = l; i < r; i++)
#define FORD(i,r,l) for (int i = r; i > l; i--)
using namespace std;
//using namespace __gnu_pbds;
//mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//mt19937_64 rng64(chrono::steady_clock::now().time_since_epoch().count());
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
//typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> bst;
namespace input {
	template<class T> inline void _R(T &x) {cin >> x;}
	inline void R() {}
	template<class T1, class... T2> inline void R(T1 &x, T2 &...y) { _R(x); R(y...);}
} using namespace input;
namespace overload_output {
	template<class T1, class T2> inline ostream& operator << (ostream& out, pair<T1,T2>& p) {return out << p.first << ' ' << p.second;}
	template<class T> inline ostream& operator << (ostream& out, vector<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, deque<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, forward_list<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, list<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, set<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, multiset<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, unordered_set<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, unordered_multiset<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, map<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, multimap<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, unordered_map<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, unordered_multimap<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
} using namespace overload_output;
namespace output {
	template<class T> inline void _W(const T& x) {cout << x;}
	template<class T1, class T2> inline void _W(const pair<T1,T2>& p) {_W(p.first); _W(' '); _W(p.second);}
	template<class T> inline void _W(const vector<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const deque<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const forward_list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2, class T3> inline void _W(const set<T1,T2,T3>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const unordered_set<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const unordered_multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const map<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const unordered_map<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const unordered_multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}

 	inline void W() {cout << '\n';}
	template<class T> inline void W(const T &x) {_W(x); W();}
	template<class T1, class... T2> inline void W(const T1 &x, const T2 &...y) { _W(x); _W(' '); W(y...);}
} using namespace output;

template<class T>
struct segment_tree{
	private:
	struct _node {
		ll _val = LLINF;
		int _idx = 0;
		int _lazy = 0;
	} nullNode;

	vector<_node> _segtree;
	int _leaf_size = 0;

	inline _node __merge(_node a, _node b) {
		_node temp;
		if (a._val < b._val) {
			temp._val = a._val;
			temp._idx = a._idx;
		} else {
			temp._val = b._val;
			temp._idx = b._idx;
		}
		return temp;
	}

	inline void __init(int id, T val, int l, int r) {
		_segtree[id]._val = val;
		_segtree[id]._idx = l;
	}

	inline void __upd(int id, T val, int l, int r) {
		_segtree[id]._val += val;
	}

	inline void __lazy_upd(int id, T newtag, int l, int r) {
		_segtree[id]._lazy += newtag;
	}

	inline void __pushdown(int id, int l, int r) {
		if (_segtree[id]._lazy != nullNode._lazy) {
			if (l < r) {
				int mid = (l+r)>>1;
				__upd(id*2,_segtree[id]._lazy,l,mid);
				__upd(id*2+1,_segtree[id]._lazy,mid+1,r);
				__lazy_upd(id*2,_segtree[id]._lazy,l,mid);
				__lazy_upd(id*2+1,_segtree[id]._lazy,mid+1,r);
			}
			_segtree[id]._lazy = nullNode._lazy;
		}
	}

 	inline void update(int id, int l, int r, int ql, int qr, T val) {
		if (qr < l || r < ql) return;
		__pushdown(id,l,r);
		if (ql <= l && r <= qr) {
			__upd(id,val,l,r);
			__lazy_upd(id,val,l,r);
			return;
		}
		int mid = (l+r)>>1;
		update(id*2,l,mid,ql,qr,val);
		update(id*2+1,mid+1,r,ql,qr,val);
		_segtree[id] = __merge(_segtree[id*2],_segtree[id*2+1]);
	}

	inline void update(int id, int l, int r, int q, T val) {
		__pushdown(id,l,r);
		if (l == r) {
			__upd(id,val,l,r);
			return;
		}
		int mid = (l+r)>>1;
		if (q <= mid)
			update(id*2,l,mid,q,val);
		else
			update(id*2+1,mid+1,r,q,val);
		_segtree[id] = __merge(_segtree[id*2],_segtree[id*2+1]);
	}

	inline _node query(int id, int l, int r, int ql, int qr) {
		if (qr < l || r < ql) return nullNode;
		__pushdown(id,l,r);
		if (ql <= l && r <= qr) return _segtree[id];
		int mid = (l+r)>>1;
		return __merge(query(id*2,l,mid,ql,qr),query(id*2+1,mid+1,r,ql,qr));
	}

	inline void build(int id, int l, int r, vector<T>& v) {
		if (l == r) {
			__init(id,v[l],l,r);
			return;
		}
		int mid = (l+r)>>1;
		build(id*2,l,mid,v);
		build(id*2+1,mid+1,r,v);
		_segtree[id] = __merge(_segtree[id*2],_segtree[id*2+1]);
	}

	public:
	inline void update(int ql, int qr, T val) {
		update(1,0,_leaf_size-1,ql,qr,val);
	}

	inline _node query(int ql, int qr) {
		return query(1,0,_leaf_size-1,ql,qr);
	}

	inline segment_tree(vector<T>& v) {
		_segtree.resize(1 << __lg(v.size()-1)+2);
		_leaf_size = v.size();
		build(1,0,v.size()-1,v);
	}

	inline segment_tree(int size) {
		_segtree.resize(1 << __lg(size-1)+2, nullNode);
		_leaf_size = size;
	}
};

int main() {
	int n; R(n);
	vector<ll> v(n); for (auto& i : v) R(i);

	segment_tree<ll> st(v);

	vector<int> ans(n);
	for (int i = 1; i <= n; i++) {
		int idx = st.query(0,n-1)._idx;
		ans[idx] = i;
		st.update(idx+1,n-1,-i);
		st.update(idx,idx,1e18);
	}

	W(ans);

 	return 0;
}

static auto _batch_ios = [](){
	#ifndef LOCAL
	ios::sync_with_stdio(false);
	cin.tie(0);
	#endif
	cout << fixed << setprecision(12);
	return 42;
}();


#pragma GCC optimize ("Ofast")
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
//#include<ext/pb_ds/assoc_container.hpp>
//#include<ext/pb_ds/tree_policy.hpp>
#define INF 2147483647
#define LLINF LLONG_MAX
#define PI 3.1415926535
#define MOD 1000000007
#define MOD2 998244353
#define SP << ' '
#define EL << '\n'
#define FL << flush
#define sqr(x) ((x)*(x))
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define distinct(x) sort(all(x)); x.resize(unique(all(x))-x.begin());
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define FOR(i,l,r) for (int i = l; i < r; i++)
#define FORD(i,r,l) for (int i = r; i > l; i--)
using namespace std;
//using namespace __gnu_pbds;
//mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//mt19937_64 rng64(chrono::steady_clock::now().time_since_epoch().count());
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
//typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> bst;
namespace input {
	template<class T> inline void _R(T &x) {cin >> x;}
	inline void R() {}
	template<class T1, class... T2> inline void R(T1 &x, T2 &...y) { _R(x); R(y...);}
} using namespace input;
namespace overload_output {
	template<class T1, class T2> inline ostream& operator << (ostream& out, pair<T1,T2>& p) {return out << p.first << ' ' << p.second;}
	template<class T> inline ostream& operator << (ostream& out, vector<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, deque<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, forward_list<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, list<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, set<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, multiset<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, unordered_set<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, unordered_multiset<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, map<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, multimap<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, unordered_map<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, unordered_multimap<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
} using namespace overload_output;
namespace output {
	template<class T> inline void _W(const T& x) {cout << x;}
	template<class T1, class T2> inline void _W(const pair<T1,T2>& p) {_W(p.first); _W(' '); _W(p.second);}
	template<class T> inline void _W(const vector<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const deque<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const forward_list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2, class T3> inline void _W(const set<T1,T2,T3>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const unordered_set<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const unordered_multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const map<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const unordered_map<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const unordered_multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}

 	inline void W() {cout << '\n';}
	template<class T> inline void W(const T &x) {_W(x); W();}
	template<class T1, class... T2> inline void W(const T1 &x, const T2 &...y) { _W(x); _W(' '); W(y...);}
} using namespace output;

template<class T>
struct segment_tree{
	private:
	struct _node {
		ll _val = LLINF;
		int _idx = 0;
		ll _lazy = 0;
	} nullNode;

	vector<_node> _segtree;
	int _leaf_size = 0;

	inline _node __merge(_node a, _node b) {
		_node temp;
		if (a._val < b._val) {
			temp._val = a._val;
			temp._idx = a._idx;
		} else {
			temp._val = b._val;
			temp._idx = b._idx;
		}
		return temp;
	}

	inline void __init(int id, T val, int l, int r) {
		_segtree[id]._val = val;
		_segtree[id]._idx = l;
	}

	inline void __upd(int id, T val, int l, int r) {
		_segtree[id]._val += val;
	}

	inline void __lazy_upd(int id, T newtag, int l, int r) {
		_segtree[id]._lazy += newtag;
	}

	inline void __pushdown(int id, int l, int r) {
		if (_segtree[id]._lazy != nullNode._lazy) {
			if (l < r) {
				int mid = (l+r)>>1;
				__upd(id*2,_segtree[id]._lazy,l,mid);
				__upd(id*2+1,_segtree[id]._lazy,mid+1,r);
				__lazy_upd(id*2,_segtree[id]._lazy,l,mid);
				__lazy_upd(id*2+1,_segtree[id]._lazy,mid+1,r);
			}
			_segtree[id]._lazy = nullNode._lazy;
		}
	}

 	inline void update(int id, int l, int r, int ql, int qr, T val) {
		if (qr < l || r < ql) return;
		__pushdown(id,l,r);
		if (ql <= l && r <= qr) {
			__upd(id,val,l,r);
			__lazy_upd(id,val,l,r);
			return;
		}
		int mid = (l+r)>>1;
		update(id*2,l,mid,ql,qr,val);
		update(id*2+1,mid+1,r,ql,qr,val);
		_segtree[id] = __merge(_segtree[id*2],_segtree[id*2+1]);
	}

	inline void update(int id, int l, int r, int q, T val) {
		__pushdown(id,l,r);
		if (l == r) {
			__upd(id,val,l,r);
			return;
		}
		int mid = (l+r)>>1;
		if (q <= mid)
			update(id*2,l,mid,q,val);
		else
			update(id*2+1,mid+1,r,q,val);
		_segtree[id] = __merge(_segtree[id*2],_segtree[id*2+1]);
	}

	inline _node query(int id, int l, int r, int ql, int qr) {
		if (qr < l || r < ql) return nullNode;
		__pushdown(id,l,r);
		if (ql <= l && r <= qr) return _segtree[id];
		int mid = (l+r)>>1;
		return __merge(query(id*2,l,mid,ql,qr),query(id*2+1,mid+1,r,ql,qr));
	}

	inline void build(int id, int l, int r, vector<T>& v) {
		if (l == r) {
			__init(id,v[l],l,r);
			return;
		}
		int mid = (l+r)>>1;
		build(id*2,l,mid,v);
		build(id*2+1,mid+1,r,v);
		_segtree[id] = __merge(_segtree[id*2],_segtree[id*2+1]);
	}

	public:
	inline void update(int ql, int qr, T val) {
		update(1,0,_leaf_size-1,ql,qr,val);
	}

	inline _node query(int ql, int qr) {
		return query(1,0,_leaf_size-1,ql,qr);
	}

	inline segment_tree(vector<T>& v) {
		_segtree.resize(1 << __lg(v.size()-1)+2);
		_leaf_size = v.size();
		build(1,0,v.size()-1,v);
	}

	inline segment_tree(int size) {
		_segtree.resize(1 << __lg(size-1)+2, nullNode);
		_leaf_size = size;
	}
};

int main() {
	int n; R(n);
	vector<ll> v(n); for (auto& i : v) R(i);

	segment_tree<ll> st(v);

	vector<int> ans(n);
	for (int i = 1; i <= n; i++) {
		int idx = st.query(0,n-1)._idx;
		ans[idx] = i;
		st.update(idx+1,n-1,-i);
		st.update(idx,idx,1e18);
	}

	W(ans);

 	return 0;
}

static auto _batch_ios = [](){
	#ifndef LOCAL
	ios::sync_with_stdio(false);
	cin.tie(0);
	#endif
	cout << fixed << setprecision(12);
	return 42;
}();


#pragma GCC optimize ("Ofast")
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
//#include<ext/pb_ds/assoc_container.hpp>
//#include<ext/pb_ds/tree_policy.hpp>
#define INF 2147483647
#define LLINF LLONG_MAX
#define PI 3.1415926535
#define MOD 1000000007
#define MOD2 998244353
#define SP << ' '
#define EL << '\n'
#define FL << flush
#define sqr(x) ((x)*(x))
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define distinct(x) sort(all(x)); x.resize(unique(all(x))-x.begin());
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define FOR(i,l,r) for (int i = l; i < r; i++)
#define FORD(i,r,l) for (int i = r; i > l; i--)
using namespace std;
//using namespace __gnu_pbds;
//mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//mt19937_64 rng64(chrono::steady_clock::now().time_since_epoch().count());
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
//typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> bst;
namespace input {
	template<class T> inline void _R(T &x) {cin >> x;}
	inline void R() {}
	template<class T1, class... T2> inline void R(T1 &x, T2 &...y) { _R(x); R(y...);}
} using namespace input;
namespace overload_output {
	template<class T1, class T2> inline ostream& operator << (ostream& out, pair<T1,T2>& p) {return out << p.first << ' ' << p.second;}
	template<class T> inline ostream& operator << (ostream& out, vector<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, deque<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, forward_list<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, list<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, set<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, multiset<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, unordered_set<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T> inline ostream& operator << (ostream& out, unordered_multiset<T>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, map<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, multimap<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, unordered_map<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
	template<class T1, class T2> inline ostream& operator << (ostream& out, unordered_multimap<T1, T2>& x) {for (auto i : x) out << i << ' '; return out;}
} using namespace overload_output;
namespace output {
	template<class T> inline void _W(const T& x) {cout << x;}
	template<class T1, class T2> inline void _W(const pair<T1,T2>& p) {_W(p.first); _W(' '); _W(p.second);}
	template<class T> inline void _W(const vector<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const deque<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const forward_list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2, class T3> inline void _W(const set<T1,T2,T3>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const unordered_set<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T> inline void _W(const unordered_multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const map<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const unordered_map<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}
	template<class T1, class T2> inline void _W(const unordered_multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; cout << i;}}

 	inline void W() {cout << '\n';}
	template<class T> inline void W(const T &x) {_W(x); W();}
	template<class T1, class... T2> inline void W(const T1 &x, const T2 &...y) { _W(x); _W(' '); W(y...);}
} using namespace output;

template<class T>
struct segment_tree{
	private:
	struct _node {
		int _val = INF;
		int _idx = 0;
		int _lazy = 0;
	} nullNode;

	vector<_node> _segtree;
	int _leaf_size = 0;

	inline _node __merge(_node a, _node b) {
		_node temp;
		if (a._val < b._val) {
			temp._val = a._val;
			temp._idx = a._idx;
		} else {
			temp._val = b._val;
			temp._idx = b._idx;
		}
		return temp;
	}

	inline void __init(int id, T val, int l, int r) {
		_segtree[id]._val = val;
		_segtree[id]._idx = l;
	}

	inline void __upd(int id, int val, int l, int r) {
		_segtree[id]._val += val;
	}

	inline void __lazy_upd(int id, int newtag, int l, int r) {
		_segtree[id]._lazy += newtag;
	}

	inline void __pushdown(int id, int l, int r) {
		if (_segtree[id]._lazy != nullNode._lazy) {
			if (l < r) {
				int mid = (l+r)>>1;
				__upd(id*2,_segtree[id]._lazy,l,mid);
				__upd(id*2+1,_segtree[id]._lazy,mid+1,r);
				__lazy_upd(id*2,_segtree[id]._lazy,l,mid);
				__lazy_upd(id*2+1,_segtree[id]._lazy,mid+1,r);
			}
			_segtree[id]._lazy = nullNode._lazy;
		}
	}

 	inline void update(int id, int l, int r, int ql, int qr, int val) {
		if (qr < l || r < ql) return;
		__pushdown(id,l,r);
		if (ql <= l && r <= qr) {
			__upd(id,val,l,r);
			__lazy_upd(id,val,l,r);
			return;
		}
		int mid = (l+r)>>1;
		update(id*2,l,mid,ql,qr,val);
		update(id*2+1,mid+1,r,ql,qr,val);
		_segtree[id] = __merge(_segtree[id*2],_segtree[id*2+1]);
	}

	inline void update(int id, int l, int r, int q, int val) {
		__pushdown(id,l,r);
		if (l == r) {
			__upd(id,val,l,r);
			return;
		}
		int mid = (l+r)>>1;
		if (q <= mid)
			update(id*2,l,mid,q,val);
		else
			update(id*2+1,mid+1,r,q,val);
		_segtree[id] = __merge(_segtree[id*2],_segtree[id*2+1]);
	}

	inline _node query(int id, int l, int r, int ql, int qr) {
		if (qr < l || r < ql) return nullNode;
		__pushdown(id,l,r);
		if (ql <= l && r <= qr) return _segtree[id];
		int mid = (l+r)>>1;
		return __merge(query(id*2,l,mid,ql,qr),query(id*2+1,mid+1,r,ql,qr));
	}

	inline void build(int id, int l, int r, vector<T>& v) {
		if (l == r) {
			__init(id,v[l],l,r);
			return;
		}
		int mid = (l+r)>>1;
		build(id*2,l,mid,v);
		build(id*2+1,mid+1,r,v);
		_segtree[id] = __merge(_segtree[id*2],_segtree[id*2+1]);
	}

	public:
	inline void update(int ql, int qr, int val) {
		update(1,0,_leaf_size-1,ql,qr,val);
	}

	inline _node query(int ql, int qr) {
		return query(1,0,_leaf_size-1,ql,qr);
	}

	inline segment_tree(vector<T>& v) {
		_segtree.resize(1 << __lg(v.size()-1)+2);
		_leaf_size = v.size();
		build(1,0,v.size()-1,v);
	}

	inline segment_tree(int size) {
		_segtree.resize(1 << __lg(size-1)+2, nullNode);
		_leaf_size = size;
	}
};

int main() {
	int n; R(n);
	vector<int> v(n); for (auto& i : v) R(i);

	segment_tree<int> st(v);

	vector<int> ans(n);
	for (int i = 1; i <= n; i++) {
		int idx = st.query(0,n-1)._idx;
		ans[idx] = i;
		st.update(idx+1,n-1,-i);
		st.update(idx,idx,1e9);
	}

	W(ans);

 	return 0;
}

static auto _batch_ios = [](){
	#ifndef LOCAL
	ios::sync_with_stdio(false);
	cin.tie(0);
	#endif
	cout << fixed << setprecision(12);
	return 42;
}();


//package Practice_Problems;
import java.util.*;
import java.io.*;
public class uniqueness
{
	static int arr[],pref[];
	static Set<Integer> set;
	static final int mod=(int)1e9+7;
	static final int inf=(int)1e9;
	static final long INF=(long)1e18;
	public static void main(String[] args)
	{
		FastScanner fs=new FastScanner();
		int n=fs.nextInt();
		arr=new int[n];
		pref=new int[n];
		set=new HashSet<>();
		for(int i=0;i<n;i++)
		{
			arr[i]=fs.nextInt();
			set.add(arr[i]);
			pref[i]=set.size();
		}
		if(set.size()==n) {System.out.println(0);return;}
		int left=1,right=n;
		int ans=inf;
		while(left<=right)
		{
			int mid=(left+right)/2;
			if(isValid(mid))
			{
				ans=Math.min(ans,mid);
				right=mid-1;
			}
			else
				left=mid+1;
		}
		System.out.println(ans+1);
	}
	public static boolean isValid(int mid)
	{
		for(int i=0;i<=arr.length-mid;i++)
		{
			Set<Integer> set2 = new HashSet<>();
			for(int j=i;j<=i+mid-1;j++)
			{
				set2.add(arr[j]);
			}
			if(i==0)
			{
				if(pref[arr.length-1]-pref[i+mid-1]==arr.length-mid)return true;
			}
			else
			{
				if((pref[arr.length-1]-set2.size()+pref[i-1])==arr.length-mid)return true;
			}
		}
		return false;
	}
}
class FastScanner
{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer("");
		public String next()
		{
			while (!st.hasMoreTokens())
				try {
					st=new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			return st.nextToken();

		}
		int[] sort(int arr[])
		{
			ArrayList<Integer> list = new ArrayList<Integer>();
			for(int i:arr)list.add(i);
			Collections.sort(list);
			for(int i=0;i<arr.length;i++)
			{
				arr[i]=list.get(i);
			}
			return arr;
		}
		char[] charsort(char arr[])
	        {
	    	ArrayList<Character> list = new ArrayList<>();
	    	for(char c:arr)list.add(c);
	    	Collections.sort(list);
	    	for(int i=0;i<list.size();i++)
	    	{
	    		arr[i]=list.get(i);
	    	}
	    	return arr;
	        }
		long[] longsort(long arr[])
		{
			ArrayList<Long> list = new ArrayList<Long>();
			for(long i:arr)list.add(i);
			Collections.sort(list);
			for(int i=0;i<arr.length;i++)
			{
				arr[i]=list.get(i);
			}
			return arr;
		}
		public int nextInt()
		{
			return Integer.parseInt(next());
		}
		public int[] readArray(int n)
		{
			int[] arr=new int[n];
			for (int i=0; i<n; i++) arr[i]=nextInt();
			return arr;
		}
		public long nextLong()
		{
			return Long.parseLong(next());
		}
		public long[] longreadArray(int n)
		{
			long[] a=new long[n];
			for (int i=0; i<n; i++) a[i]=nextLong();
			return a;
		}
}


//package Practice_Problems;
import java.util.*;
import java.io.*;
public class uniqueness
{
	static int arr[],pref[],suf[];
	static Set<Integer> set;
	static final int mod=(int)1e9+7;
	static final int inf=(int)1e9;
	static final long INF=(long)1e18;
	public static void main(String[] args)
	{
		FastScanner fs=new FastScanner();
		int n=fs.nextInt();
		arr=new int[n];
		pref=new int[n];
		set=new HashSet<>();
		for(int i=0;i<n;i++)
		{
			arr[i]=fs.nextInt();
			set.add(arr[i]);
			pref[i]=set.size();
		}
		int left=0,right=n;
		int ans=inf;
		while(left<=right)
		{
			int mid=(left+right)/2;
			//System.out.println(mid+" "+isValid(mid));
			if(isValid(mid))
			{
				ans=Math.min(ans,mid);
				right=mid-1;
			}
			else
				left=mid+1;
		}
		System.out.println(ans);
	}
	public static boolean isValid(int mid)
	{
		for(int i=0;i<=arr.length-mid;i++)
		{
			Set<Integer> set2 = new HashSet<>();
			if(i==0)
			{
				for(int j=i+mid;j<=arr.length-1;j++)
				{
					set2.add(arr[j]);
				}
				if(set2.size()==arr.length-mid)return true;
			}
			else
			{
				for(int k=0;k<i;k++)set2.add(arr[k]);
				for(int j=i+mid;j<=arr.length-1;j++)set2.add(arr[j]);
				if(set2.size()==arr.length-mid)return true;
			}
		}
		return false;
	}
}
class FastScanner
{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer("");
		public String next()
		{
			while (!st.hasMoreTokens())
				try {
					st=new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			return st.nextToken();

		}
		int[] sort(int arr[])
		{
			ArrayList<Integer> list = new ArrayList<Integer>();
			for(int i:arr)list.add(i);
			Collections.sort(list);
			for(int i=0;i<arr.length;i++)
			{
				arr[i]=list.get(i);
			}
			return arr;
		}
		char[] charsort(char arr[])
	        {
	    	ArrayList<Character> list = new ArrayList<>();
	    	for(char c:arr)list.add(c);
	    	Collections.sort(list);
	    	for(int i=0;i<list.size();i++)
	    	{
	    		arr[i]=list.get(i);
	    	}
	    	return arr;
	        }
		long[] longsort(long arr[])
		{
			ArrayList<Long> list = new ArrayList<Long>();
			for(long i:arr)list.add(i);
			Collections.sort(list);
			for(int i=0;i<arr.length;i++)
			{
				arr[i]=list.get(i);
			}
			return arr;
		}
		public int nextInt()
		{
			return Integer.parseInt(next());
		}
		public int[] readArray(int n)
		{
			int[] arr=new int[n];
			for (int i=0; i<n; i++) arr[i]=nextInt();
			return arr;
		}
		public long nextLong()
		{
			return Long.parseLong(next());
		}
		public long[] longreadArray(int n)
		{
			long[] a=new long[n];
			for (int i=0; i<n; i++) a[i]=nextLong();
			return a;
		}
}