https://codeforces.com/contest/1208/problem/D
D. Restore Permutation
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
An array of integers p1,p2,…,pn is called a permutation if it contains each number from 1 to n exactly once. For example, the following arrays are permutations: [3,1,2],[1],[1,2,3,4,5]and [4,3,1,2]. The following arrays are not permutations: [2],[1,1],[2,3,4].
There is a hidden permutation of length n.
For each index i, you are given si, which equals to the sum of all pj such that j
Your task is to restore the permutation.
Input
The first line contains a single integer nn (1≤n≤2⋅10^5) — the size of the permutation.
The second line contains nn integers s1,s2,…,sns1,s2,…,sn (0≤si≤n(n−1)/2).
It is guaranteed that the array ss corresponds to a valid permutation of length nn.
Output
Print nn integers p1,p2,…,pn— the elements of the restored permutation. We can show that the answer is always unique.
Examples
input
Copy
3 0 0 0
output
Copy
3 2 1
input
Copy
2 0 1
output
Copy
1 2
input
Copy
5 0 1 1 1 10
output
Copy
1 4 3 2 5
Note
In the first example for each i there is no index j satisfying both conditions, hence sisi are always 0.
In the second example for i=2 it happens that j=1 satisfies the conditions, so s2=p1.
In the third example for i=2,3,4 only j=1 satisfies the conditions, so s2=s3=s4=1. For i=5 all j=1,2,3,4 are possible, so s5=p1+p2+p3+p4=10.
题意:有一个序列p,给你一个序列s,s[i]的值为p[1]到p[i-1]中比p[i]小的数的和,让你求出p序列
分析:从后往前操作,这样就能通过si确定出pi是什么
查找第一个和大于s[i]的位置就是p[i],返回的时候要把p[i]减去
#include
#pragma GCC optimize(3)
#define max(a,b) a>b?a:b
using namespace std;
typedef long long ll;
const int N=2e5+5;
ll tr[N<<2];
ll s[N];
int pos[N];
void build(int l,int r,int p){
if(l==r){
tr[p]=l;
return ;
}
int mid=(l+r)>>1;
build(l,mid,p<<1);
build(mid+1,r,p<<1|1);
tr[p]=tr[p<<1]+tr[p<<1|1];
}
int query(int l,int r,int p,ll val){
if(l==r){
tr[p]=0;
return l;
}
int mid=(l+r)>>1;
int ans=0;
if(tr[p<<1]>val){
ans=query(l,mid,p<<1,val);
tr[p]-=ans;
}
else{
ans=query(mid+1,r,p<<1|1,val-tr[p<<1]);
tr[p]-=ans;
}
return ans;
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%I64d",&s[i]);
build(1,n,1);
for(int i=n;i>=1;i--){
pos[i]=query(1,n,1,s[i]);
}
for(int i=1;i<=n;i++) printf("%d%c",pos[i]," \n"[i==n]);
return 0;
}