You are given two integers n and d. You need to construct a rooted binary tree consisting of n vertices with a root at the vertex 1 and the sum of depths of all vertices equals to d.
A tree is a connected graph without cycles. A rooted tree has a special vertex called the root. A parent of a vertex v is the last different from v vertex on the path from the root to the vertex v. The depth of the vertex v is the length of the path from the root to the vertex v. Children of vertex v are all vertices for which v is the parent. The binary tree is such a tree that no vertex has more than 2 children.
You have to answer t independent test cases.
Input
The first line of the input contains one integer t (1≤t≤1000) — the number of test cases.
The only line of each test case contains two integers n and d (2≤n,d≤5000) — the number of vertices in the tree and the required sum of depths of all vertices.
It is guaranteed that the sum of n and the sum of d both does not exceed 5000 (∑n≤5000,∑d≤5000).
Output
For each test case, print the answer.
If it is impossible to construct such a tree, print “NO” (without quotes) in the first line. Otherwise, print “{YES}” in the first line. Then print n−1 integers p2,p3,…,pn in the second line, where pi is the parent of the vertex i. Note that the sequence of parents you print should describe some binary tree.
Example
Input
3
5 7
10 19
10 18
Output
YES
1 2 1 3
YES
1 2 3 3 9 9 2 1 6
NO
Note
Pictures corresponding to the first and the second test cases of the example:
思路:我们可以计算出上限和下限。如果不在这个范围内就不能构造成功。在这个范围内的都可以构造成功。那么我们可以计算出差值来,首先的状态就是值最小的时候,然后一个一个的往下移动。但是要注意必须保证上面那一层的乘以2大于等于当前层,这样才符合二叉树的标准。就是一个模拟。我看网上大佬都是一条单链开始不断的减少自己的值,可能那样更好做一些。
代码如下:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxx=5e3+100;
int a[maxx];
int ans[maxx];
int n,d;
inline int fcs(int i)
{
int _max=0;
while((a[i]-_max)*2>=(a[i+1]+_max)) _max++;
return _max-1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(a,0,sizeof(a));
scanf("%d%d",&n,&d);
int x=1,all=0;
int _min=0;
int cnt=0;
while(all+x<=n)
{
_min+=((int)log2(x)*x);
all+=x;
a[++cnt]=x;
x<<=1;
}
_min+=((int)log2(x)*((n-all)));
a[++cnt]=n-all;
int _max=(n)*(n-1)/2;
if(!(d>=_min&&d<=_max)) cout<<"NO"<<endl;
else
{
int cz=d-_min;
while(cz)
{
for(int i=cnt;i>=2&&cz;i--)
{
if(a[i]>1)
{
int zz=fcs(i);//寻找可以下移的最大个数。
if(zz<=cz) a[i+1]+=zz,a[i]-=zz,cz-=zz;
else a[i+1]+=cz,a[i]-=cz,cz=0;
if(i+1>cnt) cnt++;
}
}
}
//for(int i=1;i<=cnt;i++) cout<<a[i]<<" ";cout<<endl;
vector<int> p[cnt+1];
for(int i=1;i<=cnt;i++) p[i].clear();
int z=2;
for(int i=1;i<=cnt;i++)
{
if(i==1) p[i].push_back(1);
else
{
for(int j=0;j<p[i-1].size()&&a[i];j++)
{
if(a[i]) ans[z++]=p[i-1][j],a[i]--,p[i].push_back(z-1);
if(a[i]) ans[z++]=p[i-1][j],a[i]--,p[i].push_back(z-1);
}
}
}
cout<<"YES"<<endl;
for(int i=2;i<=n;i++) cout<<ans[i]<<" ";cout<<endl;
}
}
return 0;
}
努力加油a啊,(o)/~