jzoj2565 树的序号

31 篇文章 0 订阅
21 篇文章 0 订阅

MDZZ,这题在比赛的时候死扣了三个半小时还是没扣出来!!

这里写图片描述
首先我们设f[i]为i个点能摆成多少种树
显然有 fi=fjf(ij1) ,且对于一个序号X他的节点数nodes我们是能求出来的
可以发现最多不到20个点

然后就可以去枚举每一层的左右子树节点个数,
我们先求出序号X在所有nodes个节点的数中排第Y,方便我们计算,

因为他的判断规则是优先左子树,那么我们按左子树0,1,2,3…的顺序来枚举,当枚举到一个i,那么对应的右子树的节点数就是nodes-1-j,每过一种i,j就代表着我们取了f[i]*f[j]个总共有nodes个节点的树序号,直到我们取到没法取完整的f[i]*f[j]为止.
那么我们得到了一个l,r,表示左右子树的节点数.

确定了总节点个数与左右节点个数后,接下来就该确定序号数了.
首先我们设右子树是能取满的,也就是有f[r]个不同的子树也就代表着f[r]个序号

这就是他对答案的贡献,只要左子树每有一次不同的构造,那么序号也会增加f[r]

即左子树有多少个序号,那么每一个序号就能带来f[r]的总收益
那么我们计算,在原有的基础上还需要增加多少的序号才能到达剩下的Y(这里的Y减去了已取的序号个数)个序号.
显然需要的左子树序号是Y/f[r]个,如果能整除的话.
如果没法整除,第一感觉是取下整,但是仔细一想,多出来的余数还是得分配一个l的序号,但是这个序号带来的不是f[r]的收益而是右子树的序号. 因为收益为f[r]的右子树其实都在没有表示出来的0~左子树的序号-1里

这样就get到了左右子树序号,需要注意的是一个余数问题,如果能整除那说明的是放够f[r]个而不是右子树一个都不用放

然后就递归下去处理就可以了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值