题解 CF1311E 【Construct the Binary Tree】
为啥
首先最小值是很好求的:构建一棵满二叉树。令
同时,最大值显然是链的情况。
对于一般情况,考虑从满二叉树向链调整。每次把编号最大的,不在链上的点挂到链上。假设现在考虑
若需要增加的深度
我这里取
时间复杂度显然
/**********/
#define MAXN 200011
ll fa[MAXN],dep[MAXN];
void work()
{
ll n=read(),sum_dep=read(),cur=0,pos;
dep[0]=-1;
for(ll i=1;i<=n;++i)
{
fa[i]=i>>1;dep[i]=dep[i>>1]+1;cur+=dep[i];
if((i&(i-1))==0)pos=i;
}
sum_dep-=cur;
if(sum_dep<0){puts("NO");return;}
if(sum_dep==0)
{
puts("YES");
for(ll i=2;i<=n;++i)printf("%lld ",fa[i]);
puts("");
return;
}
for(ll i=n;i;--i)
{
if((i&(i-1))==0)continue;
sum_dep-=dep[pos]+1-dep[i];
if(sum_dep<=0)
{
while(sum_dep)pos=fa[pos],++sum_dep;
sum_dep=0;
fa[i]=pos;break;
}
fa[i]=pos,dep[i]=dep[pos]+1,pos=i;
}
if(sum_dep)puts("NO");
else
{
puts("YES");
for(ll i=2;i<=n;++i)printf("%lld ",fa[i]);
puts("");
}
}
int main()
{
ll t=read();
while(t--)work();
}