http://codeforces.com/problemset/problem/1311/E
题意:
构造一棵深度和为d的二叉树
解析:
先排成一条链,然后每次把最深的点往上提就行
代码:
/*
* Author : Jk_Chen
* Date : 2020-03-10-10.54.52
*/
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
#define debug(x) cerr<<#x<<" = "<<x<<'\n'
const LL mod=1e9+7;
const int maxn=5009;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/
int a[maxn];
int main(){
int t=rd;
while(t--){
int n=rd,m=rd;
mmm(a,0);
rep(i,0,n-1)a[i]=1;
int d=(n-1)*n/2;
if(d<m){
puts("NO");continue;
}
int mx=n-1;
while(d>m&&mx){
int hav=0;
int to=max(1,mx-(d-m));
rep(i,to,mx-1){
if(a[i]+1<=2*a[i-1]){
hav=1;
d-=mx-i;
a[mx]--;
a[i]++;
break;
}
}
if(!hav)mx--;
else{
if(a[mx]==0)mx--;
}
}
if(d!=m){puts("NO");continue;}
puts("YES");
vector<int>V;
V.pb(1);
int cnt=1;
rep(i,1,n-1){
if(a[i]==0)break;
rep(j,0,a[i]-1){
printf("%d ",V[j/2]);
}
V.clear();
rep(j,1,a[i]){
V.pb(++cnt);
}
}
puts("");
}
return 0;
}
/*_________________________________________________________end*/