time limit per test : 2 seconds
memory limit per test : 256 megabytes
An array of integers
is called a permutation if it contains each number from
to
exactly once. For example, the following arrays are permutations:
and
. The following arrays are not permutations:
.
There is a hidden permutation of length .
For each index
, you are given
, which equals to the sum of all
such that
and
. In other words, si is the sum of elements before the i-th element that are smaller than the
-th element.
Your task is to restore the permutation.
Input
The first line contains a single integer
— the size of the permutation.
The second line contains
integers
.
It is guaranteed that the array
corresponds to a valid permutation of length
.
Output
Print integers — the elements of the restored permutation. We can show that the answer is always unique.
Examples
Input
3
0 0 0
Output
3 2 1
Input
2
0 1
Output
1 2
Input
5
0 1 1 1 10
Output
1 4 3 2 5
Note
In the first example for each
there is no index j satisfying both conditions, hence
are always 0.
In the second example for
it happens that
satisfies the conditions, so
.
In the third example for only satisfies the conditions, so . For all are possible, so .
题意:
给定一个序列
,
=
,要求生成一个
的全排列
使其满足
题解:
从后往前构造解。
对于第
个位置二分满足条件的
,查询小于
的和可以用树状数组来搞定。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int lowbit(int x){return x&(-x);}
int n,a[200004];
ll s[200004];
ll tr[200004];
void add(int x,ll v){
for(int i=x;i<=n;i+=lowbit(i))tr[i]+=v;
}
ll query(int x){
ll ret=0;
for(int i=x;i>=1;i-=lowbit(i))ret+=tr[i];
return ret;
}
int Rget(ll x){
int ret=-1;
int l=1,r=n,mid;
while(l<=r){
mid=(l+r)>>1;
ll pec=query(mid-1);
if(query(mid)-pec!=0&&pec==x){
ret=mid;
add(ret,-ret);
return ret;
}
if(pec<=x)l=mid+1;
else r=mid-1;
}
}
int main(){
memset(tr,0,sizeof(tr));
scanf("%d",&n);
for(int i=1;i<=n;i++)add(i,i);
for(int i=1;i<=n;i++)scanf("%lld",&s[i]);
for(int i=n;i>=1;i--){
a[i]=Rget(s[i]);
}
for(int i=1;i<=n;i++)printf("%d ",a[i]);
puts("");
return 0;
}