[ABC264Ex] Perfect Binary Tree Solution

更好的阅读体验戳此进入

题面

存在一棵以 1 为根节点的 n 个节点的树,给定序列 Pn1 表示 [2,n] 节点的父亲。给定 k,你需要从 [1,k] 中选择一些点,对于每一个 k 一次询问,求有多少种选法使得选出的点为一棵以 1 为根节点的满二叉树。输出 k[1,n] 的答案,答案对 998244353 取模。

Solution

首先一个比较重要的性质就是 n 个节点的满二叉树层高为 log2n,所以在原树里层高超过 log2n 的节点就可以直接忽略了。

不难想到 DP,令 dp(p,i) 表示以 p 为根节点层高为 i 的满二叉树方案数。

朴素的转移十分显然,即在其儿子里找到两个层高为 i1 的满二叉树拼起来即可,即转移为:

dp(p,i)=u<v,u,vsonpdp(u,i1)×dp(v,i1)

考虑到我们每次询问都是增加一个节点,如此的转移方式复杂度显然是不正确的,考虑优化。不难想到这个式子可以转化为从和平方里去除平方和,即:

dp(p,i)=12((usonpdp(u,i1))2usonpdp(u,i1)2)

于是这个东西就可以支持 O(1) 修改了,维护一下和以及平方和即可。注意需要记录上一次的值和新的值,减去旧的加上新的。同时考虑发现每次增加一个点,将会改变该点到 1 节点的整条链,并且只会改变这些点,同时若变化的节点超过 log2n 层了那么可以直接忽略。

最终的答案即为 i=1log2ndp(1,i)

所以每次修改都是 O(logn) 的,最终答案的查询也是 O(logn) 的,最终复杂度 O(nlogn)

Code

UPD

update-2023_01_03 初稿