time limit per test : 2 seconds
memory limit per test : 256 megabytes
An array of integers
p
1
,
p
2
,
…
,
p
n
p_1,p_2,…,p_n
p1,p2,…,pn is called a permutation if it contains each number from
1
1
1 to
n
n
n exactly once. For example, the following arrays are permutations:
[
3
,
1
,
2
]
,
[
1
]
,
[
1
,
2
,
3
,
4
,
5
]
[3,1,2],[1],[1,2,3,4,5]
[3,1,2],[1],[1,2,3,4,5]and
[
4
,
3
,
1
,
2
]
[4,3,1,2]
[4,3,1,2]. The following arrays are not permutations:
[
2
]
,
[
1
,
1
]
,
[
2
,
3
,
4
]
[2],[1,1],[2,3,4]
[2],[1,1],[2,3,4].
There is a hidden permutation of length n n n.
For each index
i
i
i, you are given
s
i
s_i
si, which equals to the sum of all
p
j
p_j
pj such that
j
<
i
j<i
j<i and
p
j
<
p
i
p_j<p_i
pj<pi. In other words, si is the sum of elements before the i-th element that are smaller than the
i
i
i-th element.
Your task is to restore the permutation.
Input
The first line contains a single integer
n
(
1
≤
n
≤
2
⋅
1
0
5
)
n(1≤n≤2⋅10^5)
n(1≤n≤2⋅105) — the size of the permutation.
The second line contains
n
n
n integers
s
1
,
s
2
,
…
,
s
n
(
0
≤
s
i
≤
n
(
n
−
1
)
/
2
)
s_1,s_2,…,s_n (0≤s_i≤n(n−1)/2)
s1,s2,…,sn(0≤si≤n(n−1)/2).
It is guaranteed that the array
s
s
s corresponds to a valid permutation of length
n
n
n.
Output
Print n n n integers p 1 , p 2 , … , p n p_1,p_2,…,p_n p1,p2,…,pn— 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
i
i
i there is no index j satisfying both conditions, hence
s
i
s_i
si are always 0.
In the second example for
i
=
2
i=2
i=2 it happens that
j
=
1
j=1
j=1 satisfies the conditions, so
s
2
=
p
1
s_2=p_1
s2=p1.
In the third example for i = 2 , 3 , 4 i=2,3,4 i=2,3,4 only j = 1 j=1 j=1 satisfies the conditions, so s 2 = s 3 = s 4 = 1 s_2=s_3=s_4=1 s2=s3=s4=1. For i = 5 i=5 i=5 all j = 1 , 2 , 3 , 4 j=1,2,3,4 j=1,2,3,4 are possible, so s 5 = p 1 + p 2 + p 3 + p 4 = 10 s_5=p_1+p_2+p_3+p_4=10 s5=p1+p2+p3+p4=10.
题意:
给定一个序列
{
s
n
}
\{s_n\}
{sn},
s
i
s_i
si=
∑
p
j
<
p
i
且
j
<
i
p
j
\sum_{p_j<p_i且j<i} p_j
∑pj<pi且j<ipj,要求生成一个
n
n
n的全排列
{
p
n
}
\{ p_n \}
{pn}使其满足
{
s
n
}
\{s_n\}
{sn}
题解:
从后往前构造解。
对于第
i
i
i个位置二分满足条件的
p
i
p_i
pi,查询小于
p
i
p_i
pi的和可以用树状数组来搞定。
#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;
}