Misha walked through the snowy forest and he was so fascinated by the trees to decide to draw his own tree!
Misha would like to construct a rooted tree with n
vertices, indexed from 1 to 1
.
Below there is a tree with 6
vertices. The subtree of vertex 4
.
The branching coefficient of the tree is defined as the maximum number of children in any vertex. For example, for the tree above the branching coefficient equals 2
. Your task is to construct a tree with s
, and the branching coefficient is minimum possible.
InputThe only input line contains two integers n
and 10).
OutputIf the required tree does not exist, output «No». Otherwise output «Yes» on the first line, and in the next one output integers 2
, i.
Examples3 5
Yes 1 1
4 42
No
6 15
Yes 1 2 3 1 5
Below one can find one of the possible solutions for the first sample case. The sum of subtree sizes equals 5
, and the branching coefficient equals 2.
Below one can find one of the possible solutions for the third sample case. The sum of subtree sizes equals 15
, and the branching coefficient equals 2.
题意:给定N,S,让你构造一个大小为N的数,使得每个节点子树大小之和为S,如果存在,请构造一个树,使得儿子最多的点的儿子数量(P)最少。
思路:我们发现对于大小一定的树,越瘦长K越大(一条链,最大为N*(N+1)/2),越矮胖越小(菊花树,最小为N+N-1),那么如果K不在这个范围我们输出-1;如果在,我们一定看i有构造一个满足题意的树。 我们可以二分得到P。然后来构造。 我的构造方式是先构造一条链,此时的sum=N*(N+1)/2;如果sum>S,我们就把最下面的点移到上面的某个位置,知道sum=S。
#include<bits/stdc++.h> #define ll long long #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn=1000010;ll N,S; ll fa[maxn],q[maxn],d[maxn],head,tail,sz[maxn],son[maxn]; bool check(ll Mid) { ll tN=N,now=1,p=1,res=0; while(tN){ res+=min(p,tN)*now; if(res>S) return false; tN-=min(p,tN); p*=Mid; now++; } return true; } int main() { cin>>N>>S; ll Mn=N+N-1; ll Mx=N*(N+1)/2; if(S<Mn||S>Mx) return puts("NO"),0; ll L=1,R=N-1,Mid,res; while(L<=R){ Mid=(L+R)/2; if(check(Mid)) res=Mid,R=Mid-1; else L=Mid+1; } puts("YES"); rep(i,1,N) sz[i]=1; ll Now=Mx,D=2; for(int i=N;;i--){ if(Now==S) break; if(sz[D]==sz[D-1]*res) D++; if(Now-S>=i-D){ sz[D]++; sz[i]--; Now-=(i-D); } else { sz[i]--; sz[i-(Now-S)]++; Now=S; } } head=tail=1; q[head]=1; d[1]=1; ll p=1; rep(i,2,N) { if(sz[i]==0) break; L=p+1; R=p+sz[i]; rep(j,L,R){ while(d[q[head]]!=i-1||son[q[head]]==res){ head++; } fa[j]=q[head]; son[q[head]]++; q[++tail]=j; d[j]=i; } p=R; } rep(i,2,N) printf("%lld ",fa[i]); return 0; }