Solution

预处理出 \(i\) 个点组成的二叉树的最大答案和最小答案

递归做,由于只需要构造一种方案,我们让左子树大小能小就小,因此每次从小到大枚举左子树的点数并检验,如果检验通过就选定之

现在还需要确定左右子树各分配多少答案上去,一种构造性的想法是,要么让左子树选最小,要么让右子树选最大。对于任意一种其它方案,我们可以通过把左子树上的答案不断移到右子树上,直到某一边达到界限,故等价。

打错变量名查半天……

#include <bits/stdc++.h>
using namespace std; #define int long long
const int N = 5005; int T,n,d,mx[N],mn[N],f[N]; void dfs(int tot,int off,int sum) {
for(int i=0;i<tot;i++) {
int lsiz=i, rsiz=tot-1-i;
int vmin=mn[lsiz]+mn[rsiz]+tot-1;
int vmax=mx[lsiz]+mx[rsiz]+tot-1;
if(vmin<=sum && sum<=vmax) {
int tmp=mn[lsiz];
if(mn[lsiz]+mx[tot-1-lsiz]+tot-1<sum) tmp=sum-tot+1-mx[tot-1-lsiz];
if(lsiz) {
f[off+1]=off;
dfs(lsiz,off+1,tmp);
}
if(rsiz) {
f[off+1+lsiz]=off;
dfs(rsiz,off+1+lsiz,sum-tot+1-tmp);
}
return;
}
}
} signed main() {
ios::sync_with_stdio(false);
for(int i=1;i<=5000;i++) {
mx[i]=i*(i-1)/2;
mn[i]=mn[i-1]+(int)(log2(i)+1e-7);
} cin>>T;
while(T--) {
cin>>n>>d;
if(d<mn[n] || d>mx[n]) cout<<"NO"<<endl;
else {
cout<<"YES"<<endl;
dfs(n,1,d);
for(int i=2;i<=n;i++) cout<<f[i]<<" ";
cout<<endl;
}
}
}

最新文章

  1. JavaScript Object对象
  2. 十分钟了解分布式计算:Spark
  3. 网络存储(三)之ISCSI搭建的入门
  4. Linux下查看mysql、apache是否安装,安装,卸载等操作
  5. 克隆或拷贝的VMware虚拟机IP问题解决
  6. varchar(10)与nvarchar(10)有什么区别
  7. Java Synchronized Blocks vs. Methods
  8. 【BZOJ】【2179】FFT快速傅里叶
  9. 关于特殊文件权限:suid、sgid和sticky-bit
  10. Ubuntu下Apache中部署Django
  11. 用 async/await 来处理异步
  12. cmd的变量总结
  13. ElasticSearch(十一)Elasticsearch清空指定Index/Type数据
  14. CSS之设置滚动条样式
  15. Python基础(6)——装饰器
  16. Linux开启root用户
  17. Mariadb-10.1.22配置项
  18. 从零开始学Kotlin-枚举(9)
  19. LoadRunner11支持的浏览器小结-Loadrunner11打不开IE浏览器的问题
  20. 【转】Hadoop HDFS分布式环境搭建

热门文章

  1. Java并发读书笔记:如何实现线程间正确通信
  2. AI产品经理工作流程——需求分析和产品设计
  3. Go语言实现:【剑指offer】二叉树的镜像
  4. postman之设置token
  5. Redis Cluster 集群扩容与收缩
  6. CVE-2020-0618 SQL 远程代码执行
  7. 对象级别锁 vs 类级别锁(Java)
  8. QT学习之路-QT服务器-mysql数据库相关问题集锦(1)
  9. jps jmap 的使用
  10. Verilog HDL学习_1:分频器/PWM的实现