谜一样的牛

动态维护01序列中第k个1的位置

为了配合树状数组 采用枚举每一位的方式来构成长度

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;

const int N=1e5+10;

int read()
{
	int x=0,f=0,c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	return f?-x:x;
}
int n,T;
int t[N],a[N],ret[N];
void add(int x,int y){ while(x<=n){t[x]+=y; x+=x&-x; } }
int query(int x){ int ans=0; while(x){ ans+=t[x]; x-=x&-x;} return ans; }

int find(int k)
{
	int sum=0,ans=0;
	for(int p=T;p>=0;p--)
	{
		int tmp=1<<p;
		if(ans+tmp<=n&&sum+t[ans+tmp]<k)
			sum+=t[ans+tmp],ans+=tmp;
	}
	return ans+1;
}

int main()
{
	n=read(); T=log2(n);
	for(int i=2;i<=n;i++) a[i]=read();
	for(int i=1;i<=n;i++) add(i,1);
	for(int i=n;i>=1;i--)
	{
		int h=find(a[i]+1);
		ret[i]=h;
		add(h,-1);
	}
	for(int i=1;i<=n;i++) printf("%d\n",ret[i]);
	
	return 0;
}
posted @ 2022-02-08 10:37  __iostream  阅读(78)  评论(0)    收藏  举报