#include<cstdio>
#include<cstring>
const int N=1e4;
int sum[N*2],a[N];
int n;
int lowbit(int x)
{
return x&(-x);
}
void update(int x)//树状数组维护尾端比前端小的个数
{
while(x<=n)
{
sum[x]+=1;
x+=lowbit(x);
}
}
int query(int x)//查询在尾端比它小的个数
{
int ret=0;
while(x>0)
{
ret+=sum[x];
x-=lowbit(x);
}
return ret;
}
int bs(int x)//二分查找编号
{
int l=1,r=n;
while(l<r)
{
int mid=l+r>>1;
int num=query(mid);//在尾端比它小的个数
if(mid-1-num>=x)r=mid;//等于时不一定就是答案
else l=mid+1;
}
return l;
}
int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%d",&n))
{
memset(sum,0,sizeof(sum));
a[0]=0;
for(int i=1;i<n;i++)
scanf("%d",&a[i]);
for(int i=n-1;i>=0;i--)//从队尾开始找
{
int x=bs(a[i]);
a[i]=x;
update(x);
}
for(int i=0;i<n;i++)
printf("%d\n",a[i]);
}
return 0;
}
【题解】poj2182(2018-07-23校赛 树的重心-字典树-tree dp入门-树状数组入门 G)树状数组+二分
最新推荐文章于 2020-03-26 08:50:46 发布