题目传送门

  传送点I

  传送点II

  传送点III

题目大意

  每个点的权值$c\in {c_{1}, c_{2}, \cdots, c_{n}}$,问对于每个$1\leqslant s\leqslant m$有多少种不同的这样的有根二叉树满足所有点的点权和等于$s$。

  先考虑一下怎么用dp来做。

  设$f_{n}$表示点权和为$n$的满足条件的二叉树的个数,那么有:

$f_{n} = \sum_{c \in C}\sum_{i = 0}^{n - c}f_{i}f_{n - c - i}$

  初值满足$f_{0} = 1$。

  注意到右边的式子有点像卷积,考虑$f_{n}$的普通生成函数$F(x) = \sum_{n = 0}f_{n}x^{n}$。

  将$F(x)$平方就能得到$f\otimes f$的生成函数。我们用它替换右半边,得到了:

$F(x) = \sum_{c \in C}x^{c}F^2(x) + 1$

  设某个常数$A = \sum_{c \in C}x^{c}$,则有$A\cdot F^2(x) - F(x) + 1$。

  解得$F_{1}(x) = \frac{1 + \sqrt{1 - 4A}}{2A}, F_{2}(x) = \frac{1 - \sqrt{1 - 4A}}{2A} = \frac{1 - (1 - 4A)}{2A\sqrt{1 + 4A}} = \frac{2}{\sqrt{1 + 4A}}$。

  我们考虑$F_{1}(x)$的分母的常数项,它是2,分子的常数项为0,然后求逆的时候就会出事情。

  但是$F_{2}(x)$可以通过恒等变换使得分母的常数项为非0。

  然后做一次多项式开根,一次多项式求逆就做完了。

Code

 /**
* Codeforces
* Problem#438E
* Accepted
* Time: 1091ms
* Memory: 5100k
*/
#include <bits/stdc++.h>
using namespace std;
typedef bool boolean; const int N = ;
const int bzmax = ;
const int M = ;
const int g = ;
const int inv2 = (M + ) >> ; int qpow(int a, int p) {
if (p < )
p += M - ;
int rt = , pa = a;
for ( ; p; p >>= , pa = pa * 1ll * pa % M)
if (p & )
rt = rt * 1ll * pa % M;
return rt;
} int add(int a, int b) {
return ((a += b) >= M) ? (a - M) : (a);
} int sub(int a, int b) {
return ((a -= b) < ) ? (a + M) : (a);
} class NTT {
public:
int gn[bzmax], _gn[bzmax]; NTT() {
for (int i = , L = ; i < bzmax; i++, L <<= ) {
gn[i] = qpow(g, (M - ) / L);
_gn[i] = qpow(g, -(M - ) / L);
}
} void operator () (int* f, int len, int sgn) {
for (int i = , j = len >> , k; i < len - ; i++, j += k) {
if (i < j)
swap(f[i], f[j]);
for (k = len >> ; j >= k; j -= k, k >>= );
} for (int b = , t = ; b <= len; b <<= , t++) {
int wn = ((sgn > ) ? (gn[t]) : (_gn[t])), w = , hb = b >> ;
for (int i = ; i < len; i += b, w = )
for (int j = i; j < i + hb; j++, w = w * 1ll * wn % M) {
int a = f[j], b = f[j + hb] * 1ll * w % M;
f[j] = add(a, b);
f[j + hb] = sub(a, b);
}
} if (sgn < ) {
int invlen = qpow(len, -);
for (int i = ; i < len; i++)
f[i] = f[i] * 1ll * invlen % M;
}
} int correctLen(int n) {
int m = ;
while (m < n) m <<= ;
return m;
}
}NTT; template<typename T>
void pcopy(T* ns, T* ne, const T* os) {
for ( ; ns != ne; *ns = *os, ns++, os++);
} template<typename T>
void pfill(T* ps, T* pt, T val) {
for ( ; ps != pt; *ps = val, ps++);
} void debug(const int* f, int n) {
for (int i = ; i < n; i++)
cerr << f[i] << " ";
cerr << endl;
} void pol_inverse(int *f, int *g, int n) {
static int h[N];
if (n == )
g[] = qpow(f[], -);
else {
pol_inverse(f, g, (n + ) >> ); int t = NTT.correctLen(n << | );
pcopy(h, h + n, f);
pfill(h + n, h + t, );
NTT(h, t, );
NTT(g, t, );
for (int i = ; i < t; i++)
g[i] = g[i] * 1ll * sub(, g[i] * 1ll * h[i] % M) % M;
NTT(g, t, -);
pfill(g + n, g + t, );
}
} void pol_sqrt(int *f, int *g, int n) {
static int C[N], D[N];
if (n == )
g[] = ;
else {
pol_sqrt(f, g, (n + ) >> ); int t = NTT.correctLen(n << );
pcopy(C, C + n, f);
pfill(C + n, C + t, );
pfill(D, D + t, );
pol_inverse(g, D, n);
NTT(C, t, );
NTT(D, t, );
NTT(g, t, );
for (int i = ; i < t; i++)
g[i] = add(C[i] * 1ll * D[i] % M, g[i]) * 1ll * inv2 % M;
NTT(g, t, -);
pfill(g + n, g + t, );
}
} int n, m;
int C[N], qC[N]; inline void init() {
scanf("%d%d", &n, &m);
for (int i = , x; i <= n; i++) {
scanf("%d", &x);
if (x <= m)
C[x] = -;
}
} inline void solve() {
C[]++, m++;
pol_sqrt(C, qC, m);
qC[]++;
pfill(C, C + m, );
pol_inverse(qC, C, m);
for (int i = ; i < m; i++)
printf("%d\n", add(C[i], C[i]));
} int main() {
init();
solve();
return ;
}

Codeforces 438E The Child and Binary Tree - 生成函数 - 多项式的更多相关文章

  1. Codeforces 438E The Child and Binary Tree [DP,生成函数,NTT]

    洛谷 Codeforces 思路 看到计数和\(998244353\),可以感觉到这是一个DP+生成函数+NTT的题. 设\(s_i\)表示\(i\)是否在集合中,\(A\)为\(s\)的生成函数,即 ...

  2. Codeforces 438E. The Child and Binary Tree 多项式,FFT

    原文链接www.cnblogs.com/zhouzhendong/p/CF438E.html 前言 没做过多项式题,来一道入门题试试刀. 题解 设 $a_i$ 表示节点权值和为 $i$ 的二叉树个数, ...

  3. cf438E. The Child and Binary Tree(生成函数 多项式开根 多项式求逆)

    题意 链接 Sol 生成函数博大精深Orz 我们设\(f(i)\)表示权值为\(i\)的二叉树数量,转移的时候可以枚举一下根节点 \(f(n) = \sum_{w \in C_1 \dots C_n} ...

  4. 【CF438E】The Child and Binary Tree(多项式运算,生成函数)

    [CF438E]The Child and Binary Tree(多项式运算,生成函数) 题面 有一个大小为\(n\)的集合\(S\) 问所有点权都在集合中,并且点权之和分别为\([0,m]\)的二 ...

  5. 【CF】438E. The Child and Binary Tree

    http://codeforces.com/contest/438/problem/E 题意:询问每个点权值在 $c_1, c_2, ..., c_m$ 中,总权值和为 $s$ 的二叉树个数.请给出每 ...

  6. CF438E The Child and Binary Tree 生成函数、多项式开根

    传送门 设生成函数\(C(x) = \sum\limits_{i=0}^\infty [\exists c_j = i]x^i\),答案数组为\(f_1 , f_2 , ..., f_m\),\(F( ...

  7. CF 438E The Child and Binary Tree

    BZOJ 3625 吐槽 BZOJ上至今没有卡过去,太慢了卡得我不敢交了…… 一件很奇怪的事情就是不管是本地还是自己上传数据到OJ测试都远远没有到达时限. 本题做法 设$f_i$表示权值为$i$的二叉 ...

  8. bzoj 3625(CF 438E)The Child and Binary Tree——多项式开方

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3625 http://codeforces.com/contest/438/problem/E ...

  9. Codeforces 250 E. The Child and Binary Tree [多项式开根 生成函数]

    CF Round250 E. The Child and Binary Tree 题意:n种权值集合C, 求点权值和为1...m的二叉树的个数, 形态不同的二叉树不同. 也就是说:不带标号,孩子有序 ...

随机推荐

  1. docker 手动清理私有仓库的方法

    1.关于删除私有仓库的镜像,官网说明如下: 官网上注明可以通过name和digest删除image.name我们是知道的.我们只要获取digest就可以了! 查看所有镜像: 查看指定镜像: 2.reg ...

  2. Vue2学习笔记:计算属性(computed)

    参考:https://www.cnblogs.com/zycbloger/p/6428907.html

  3. JAVA课程课后作业03之作业一

    作业:使用类的静态字段和构造函数,可以跟踪某个类所创建对象的个数.请写一个类,在任何时候都可以向它查询“你已经创建了多少个对象?”. 代码: package TestJava; import java ...

  4. JBPM工作流(一)——实现一个简单的工作流例子

    一.JBPM定义 JBPM,全称是Java Business Process Management(业务流程管理),它是覆盖了业务流程管理.工作流.服务协作等领域的一个开源的.灵活的.易扩展的可执行流 ...

  5. ArcGIS AddIn调用ArcMap自带的对话框

    ESRI.ArcGIS.Framework命名空间提供了ArcGIS常用的一些对话框,可以在开发时直接调用这些对话框,而不需要重新去写Form 主要对话框有 1.IColorBrowser/IColo ...

  6. 剑指offer——python【第15题】反转链表

    题目描述 翻转一个链表 样例:给出一个链表1->2->3->null,这个翻转后的链表为3->2->1->null 思路 一种比较简单的方法是用“摘除法”.就是先新 ...

  7. js运用2

    1.变量提升 变量提升是浏览器的一个功能,在运行js代码之前,浏览器会给js一个全局作用域叫window,window分两个模块,一个叫内存模块,内存模块找到当前作用域下的所有的带var和functi ...

  8. sql 查分数段人数

    select count(case 分数字段 when 100 then 1 end) as [满分],count(case when 分数字段 between 90 and 99 then 1 en ...

  9. 图->有向无环图->求关键路径

    文字描述 与AOV-网相对应的是AOE-网(Activity on Edge)即边表示活动的网.AOE-网是一个带权的有向无环图.其中,顶点表示事件Event,弧表示活动,权表示活动持续的时间.通常, ...

  10. filter过滤器实现验证跳转_返回验证结果

    1. 需求背景 需要对某个请求url进行拦截,模拟是否可以进入某一个接口,如果拦截需要返回数据false,别问我为何不用intercept拦截器. 2. web.xml <filter> ...