[codeforces1208D]Restore Permutation

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 is called a permutation if it contains each number from 1 1 to 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] and [ 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] .

There is a hidden permutation of length n n .

For each index i i , you are given s i s_i , which equals to the sum of all p j p_j such that j < i j<i and p j < p i p_j<p_i . In other words, si is the sum of elements before the i-th element that are smaller than the 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) — the size of the permutation.
The second line contains 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) .
It is guaranteed that the array s s corresponds to a valid permutation of length n n .

Output

Print n n integers p 1 , p 2 , , p n p_1,p_2,…,p_n — 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 there is no index j satisfying both conditions, hence s i s_i are always 0.
In the second example for i = 2 i=2 it happens that j = 1 j=1 satisfies the conditions, so s 2 = p 1 s_2=p_1 .

In the third example for i = 2 , 3 , 4 i=2,3,4 only j = 1 j=1 satisfies the conditions, so s 2 = s 3 = s 4 = 1 s_2=s_3=s_4=1 . For i = 5 i=5 all 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 .

题意:
给定一个序列 { s n } \{s_n\} s i s_i = p j < p i j < i p j \sum_{p_j<p_i且j<i} p_j ,要求生成一个 n n 的全排列 { p n } \{ p_n \} 使其满足 { s n } \{s_n\}

题解:
从后往前构造解。
对于第 i i 个位置二分满足条件的 p i p_i ,查询小于 p i p_i 的和可以用树状数组来搞定。

#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;
}
发布了302 篇原创文章 · 获赞 19 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/dxyinme/article/details/100181239