[BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆)
[BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆) 题面 一棵二叉树的所有点的点权都是给定的集合中的一个数。 让你求出1到m中所有权值为i的二叉树的个数。 两棵树不同当且仅当树的形态不一样或者是树的某个点的点权不一样 分析 设 \(c(i)\) 表示数值i是否在集合中。 \(f(i)\) 表示权值为i的二叉树的个数。那么 \[f(n)=\sum_{i=1}^n c(i) \sum_{j=0}^{n-i} f(j)f(n-i-j)\] 其中 \(i\) 表示根节点的权值,那么左右子树的权值和为 \(n-i\) ,枚举左右子树分别的权值 \(j,n-i-j\) ,为 \(\sum_{j=0}^{n-i} f(j)f(n-i-j)\) 我们把式子化成卷积的形式,设 \(F,C\) 为 \(f,c\) 的生成函数 \(F(x)=F(x)^2C(x)+1\) 解函数方程,得: \[F(x)=\frac{1 \pm {\sqrt {1-4C(x)}} }{ 2C(x)}=\frac{2}{1 \mp \sqrt{1-4C(x)}}\] 如果符号取-,那么x=0时分母为0无意义。 因此 \(F(x)=\frac{2}{1+\sqrt{1-4C(x)}}\) 多项式开方和多项式求逆即可。 代码 #include<iostream>