CF-div3-624-E. Construct the Binary Tree
debug一中午,补题时间不可控啊
思路
1.先当作一整条链来做,这样深度最深,记作cnt
2.再从底向上,一个点一个点选择位置,选择什么样的位置?从上到下数要是这一层有空位就放进去,也就是构造成满二叉树的形状
每次选位置的时候算一下距离cnt-deep能不能凑成d
代码
没去CF交,不知道有没有ac,不管了,万一交了又..模拟写的太烦了,一中午没了要念首诗冷静下
AC了AC了!
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5100;
int t;
int n,d,cnt = 0;
int depth[maxn];
int deepNum[maxn],finalNum[maxn];
int fa[maxn];
int nodeNum,height;
void init(){
cnt = 0;
for(int i=0;i<=n;i++){
finalNum[i] = 0,deepNum[i] = 0;
}
for(int i=0;i<=n-1;i++)
depth[i] = i,cnt+=i,deepNum[i]++,fa[i]=0;
nodeNum = n-1,height = 1;
}
int getDeep(){
if(deepNum[height] < pow(2,height)){
// cout<<nodeNum<<" "<<height<<" "<<deepNum[height]<<" "<<pow(2,height)<<endl;
deepNum[height]++;
}else{
height++;
deepNum[height]++;
}
return height;
}
void print(){
for(int i=1;i<=n-1;i++) printf("%d%c",depth[i],i==n?'\n':' ');
}
int main(){
cin>>t;
while(t--){
cin>>n>>d;
init();
if(cnt < d){
puts("NO");
continue;
}
while(cnt > d){
int height = getDeep();
if(height>=nodeNum) break;
int value1 = nodeNum - height;
int value2 = cnt - d;
if(value1 <= value2){
depth[nodeNum] = height;
cnt -= value1;
}else{
depth[nodeNum] -= value2;
cnt = d;
}
nodeNum--;
}
// print();
if(cnt != d){
puts("NO");
continue;
}
puts("YES");
for(int i=1;i<=n-1;i++){
for(int j=0;j<=n-1;j++){
if(depth[j] == depth[i] - 1 && finalNum[j] < 2){
fa[i] = j;
finalNum[j]++;
break;
}
}
}
for(int i=1;i<=n-1;i++){
printf("%d%c",fa[i]+1,i==n-1 ? '\n':' ');
}
}
return 0;
}
/*
3
5 7
10 19
10 18
1
5 7
1
10 19
*/