问题描述
蒜头君所在的“蒜厂”在玩一个奇怪的报数游戏。一共有 n 个人参与游戏(蒜头君不在其中),首先给每个人一个编号,分别为 1,2,3,…,n。之后,这些人按照某个顺序站成一队,并告诉蒜头君,他们各自前面有多少人的编号比自己小。
现在,你能帮蒜头计算出来队伍中每个人的编号依次是多少么?
输入格式
第一行一个整数 N(2≤N≤500000)。
第 2 行到第 N 行,每行一个整数,其中第 i 行表示第 i+1i+1i+1 个人前面有多少人的编号比他小;
第一个人的前面没有任何人,所以无需输入他报的结果。
输出格式
一共 N 行,每行一个整数,表示每个人的编号。
样例输入
5
1
2
1
0
样例输出
2
4
5
3
1
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAX_N=(5e5)+50;
int C[MAX_N];
int n;
int dat[MAX_N];
int myans[MAX_N];
int lowbit(int p){
return p&(-p);
}
void change(int p,int v){
for(;p<=n;p+=lowbit(p)){
C[p]+=v;
}
return;
}
int getsum(int p){
int res=0;
for(;p;p-=lowbit(p)){
res+=C[p];
}
return res;
}
int find(int l,int r,int gobal){
if(l==r)return l;
int mid=(l+r)/2;
int t=getsum(mid)-getsum(l-1);
if(t>gobal)return find(l,mid-1,gobal);
else if(t<gobal)return find(mid+1,r,gobal-t);
else return find(l,mid,gobal);
}
int main(){
memset(C,0,sizeof(C));
memset(myans,1,sizeof(myans));
cin>>n;
for(int i=2;i<=n;i++){
scanf("%d",&dat[i]);
}
for(int i=1;i<=n;i++){
change(i,1);
}
for(int i=n;i>=1;i--){
int ans=find(1,n,dat[i]+1);
change(ans,-1);
myans[i]=ans;
}
for(int i=1;i<=n;i++)printf("%d\n",myans[i]);
return 0;
}