题目传送门

  传送点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. tensorflow 在windows下的安装

    anaconda3 python3.5 tensorflow 在 windows下的安装 1.安装Anaconda 清华的镜像:https://mirrors.tuna.tsinghua.edu.cn ...

  2. web.py框架之基本应用

    一.基本应用 1.1 Hello World! # coding:utf-8 import web urls = ( "/.*", "Tk_online" ) ...

  3. python语法_终止循环_break_continue

    break 终止整个循环计算 continue 终止本次循环,continue前的代码执行,continue后的代码不执行,下次循环继续.

  4. 360自带--JS开发工具箱

    360自带–JS开发工具箱 360自带–JS开发工具箱 360自带–JS开发工具箱

  5. 复习C++:VS2008中的宏干嘛用的

    VS2008中有宏,可也进行编辑和设置. 好处: 1.快速生成代码,帮助开发. 2.个人定制化功能,IDE更合适自己用. 3.提升编程效率.   缺点: 使用VB开发,一开始用起来费事.不过有官方参考 ...

  6. MAC OS X&Vmware

    推出共享文件恢复解决办法: 将/Volumes/VMware shared Folders 文件删除(此时这个文件中的内容为乱码) ,生成一个 VMware shared Folders文件夹,重新设 ...

  7. Ubuntu上Qt+Tcp网络编程之简单聊天对话框

    首先看一下实现结果: >>功能: (1)服务器和客户端之间进行聊天通信: (2)一个服务器可同时给多个客户端发送消息:(全部连接时)   也可以只给特定的客户端发送消息:(连接特定IP) ...

  8. bugfree3.0.1-邮件配置

    系统内新建BUG或Case,或者BUG状态有修改时,这些操作都可以伴随邮件通知,提醒指派和抄送给对象及时关注. 配置方法 1.进入C:\xampp\htdocs\bugfree\protected\c ...

  9. python基础(11)-常用模块

    re(正则)模块 常用方法 findall() 以列表返回所有满足条件的结果 import re print(re.findall('\d','a1b2c2abc123'))#['1', '2', ' ...

  10. Cartographer源码阅读(6):LocalTrajectoryBuilder和PoseExtrapolator

    LocalTrajectoryBuilder意思是局部轨迹的构建,下面的类图中方法的参数没有画进去. 注意其中的三个类:PoseExtrapolator类,RealTimeCorrelativeSca ...