题目链接
思路:
若想得知某个位置的排名
我们仅需知道这个位置前面比它小的数的个数n(即题目输入)
以及这个位置后面比它小的数(利用树状数组求)
那么这个位置的排名即为n+m+1
由于n已知
二分枚举出m即可
#include<iostream>
#include<string>
#include<string.h>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<map>
#include<set>
#include<cmath>
using namespace std;
#define ll long long
#define pi acos(-1)
const int maxn = 1e6+5;
int data[maxn]; //题目给出的数组
int n;
int lowbit(int x)
{
return x&(-x);
}
/*----------单点修改---------*/
inline void update1(int k,int x)
{
for(int i=k;i<=n;i+=lowbit(i))
data[i] += x;
}
/*----------区间查询---------*/
inline int search1(int l,int r)
{
int ans = 0;
for(int i=r;i;i-=lowbit(i))
ans += data[i];
for(int i=l-1;i;i-=lowbit(i))
ans -= data[i];
return ans;
}
/*----------区间修改---------*/
inline void update2(int l,int r,int x)
{
update1(l,x);
update1(r+1,-x);
}
/*----------单点查询---------*/
inline int search2(int l)
{
int ans = 0;
for(int i=l;i;i-=lowbit(i))
ans += data[i];
return ans;
}
int a[maxn];
int ans[maxn];
signed main()
{
scanf("%d",&n);
for(int i=2;i<=n;++i) scanf("%d",&a[i]);
for(int i=n;i;--i)
{
int l = 1;
int r = n;
while(l<=r)
{
int mid = (l+r)>>1;
if(search2(mid)+a[i]+1<=mid) r = mid - 1;
else l = mid + 1;
}
ans[i] = l;
update1(l,1);
}
for(int i=1;i<=n;++i) printf("%d\n",ans[i]);
return 0;
}