CF438E The Child and Binary Tree(生成函数,NTT)
题目大意:有 $n$ 个互不相同的正整数 $c_i$。问对于每一个 $1\le i\le m$,有多少个不同形态(考虑结构和点权)的二叉树满足每个点权都在 $c$ 中出现过,且点权和为 $i$。答案对 $998244353$ 取模。
$1\le n,m\le 10^5$。
首先考虑DP,$f_i$ 表示点权和为 $i$ 的树数。
那么枚举根节点的点权和两棵子树的点权和 $f_k=\sum\limits^n_{i=1}c_i\sum\limits^{k-c_i}_{j=0}f_jf_{k-c_i-j}$。
初始状态 $f_0=1$。因为空树也能作为子树。
这样的复杂度是 $O(nm^2)$,不能过。
考虑 $c$ 的生成函数 $C(x)=\sum x^{c_i}$ 和 $f$ 的生成函数 $F(x)=\sum f_ix^i$。(你问我怎么想到的?我也不知道啊)
那么容易发现原来的式子就是几个函数的卷积。
$F=C\times F\times F+1$(注意 $f_0=1$)
$C\times F^2-F+1=0$
$F=\dfrac{1\pm\sqrt{1-4C}}{2C}$
接下来看看上面该取正还是负。
取正时 $\lim\limits_{x\rightarrow 0}F(x)=+\infty$,不收敛,舍去。
取负时 $\lim\limits_{x\rightarrow 0}F(x)=1$,符合题意。
那么 $F=\dfrac{1-\sqrt{1-4C}}{2C}=\dfrac{2}{1+\sqrt{1-4C}}$。
直接套模板即可。时间复杂度 $O(m\log m)$。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=,mod=;
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
char ch=getchar();int x=,f=;
while(ch<'' || ch>'') f|=ch=='-',ch=getchar();
while(ch>='' && ch<='') x=x*+ch-'',ch=getchar();
return f?-x:x;
}
int n,m,c[maxn],lim,l,rev[maxn],invtmp[maxn],Binv[maxn],sqrtmp[maxn],Csqrt[maxn],Cinv[maxn];
inline void init(int upr){
for(lim=,l=;lim<upr;lim<<=,l++);
FOR(i,,lim-) rev[i]=(rev[i>>]>>)|((i&)<<(l-));
}
inline int add(int a,int b){return a+b<mod?a+b:a+b-mod;}
inline int sub(int a,int b){return a<b?a-b+mod:a-b;}
inline int qpow(int a,int b){
int ans=;
for(;b;b>>=,a=1ll*a*a%mod) if(b&) ans=1ll*ans*a%mod;
return ans;
}
void NTT(int *A,int tp){
FOR(i,,lim-) if(i<rev[i]) swap(A[i],A[rev[i]]);
for(int i=;i<lim;i<<=)
for(int j=,r=i<<,Wn=qpow(,mod-+tp*(mod-)/r);j<lim;j+=r)
for(int k=,w=;k<i;k++,w=1ll*w*Wn%mod){
int x=A[j+k],y=1ll*A[i+j+k]*w%mod;
A[j+k]=add(x,y);A[i+j+k]=sub(x,y);
}
if(tp==-) for(int i=,linv=qpow(lim,mod-);i<lim;i++) A[i]=1ll*A[i]*linv%mod;
}
void poly_inv(int *A,int *B,int deg){
if(deg==) return void(B[]=qpow(A[],mod-));
poly_inv(A,B,(deg+)>>);
init(deg<<);
FOR(i,,deg-) invtmp[i]=A[i];
FOR(i,deg,lim-) invtmp[i]=;
NTT(invtmp,);NTT(B,);
FOR(i,,lim-) B[i]=1ll*sub(,1ll*invtmp[i]*B[i]%mod)*B[i]%mod;
NTT(B,-);
FOR(i,deg,lim-) B[i]=;
}
void poly_sqrt(int *A,int *B,int deg){
if(deg==) return void(B[]=);
poly_sqrt(A,B,(deg+)>>);
init(deg<<);
FOR(i,,lim-) Binv[i]=;
poly_inv(B,Binv,deg);
init(deg<<);
FOR(i,,deg-) sqrtmp[i]=A[i];
FOR(i,deg,lim-) Binv[i]=sqrtmp[i]=;
NTT(sqrtmp,);NTT(Binv,);
FOR(i,,lim-) sqrtmp[i]=1ll*sqrtmp[i]*Binv[i]%mod;
NTT(sqrtmp,-);
FOR(i,,deg-) B[i]=499122177ll*add(B[i],sqrtmp[i])%mod;
FOR(i,deg,lim-) B[i]=;
}
int main(){
n=read();m=read();
FOR(i,,n){
int x=read();
if(x<=m) c[x]=;
}
FOR(i,,m) c[i]=(mod-4ll*c[i]%mod)%mod;
c[]=;
poly_sqrt(c,Csqrt,m+);
Csqrt[]=add(Csqrt[],);
poly_inv(Csqrt,Cinv,m+);
FOR(i,,m) printf("%d\n",add(Cinv[i],Cinv[i]));
}
CF438E The Child and Binary Tree(生成函数,NTT)的更多相关文章
- 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( ...
- cf438E. The Child and Binary Tree(生成函数 多项式开根 多项式求逆)
题意 链接 Sol 生成函数博大精深Orz 我们设\(f(i)\)表示权值为\(i\)的二叉树数量,转移的时候可以枚举一下根节点 \(f(n) = \sum_{w \in C_1 \dots C_n} ...
- [题解] CF438E The Child and Binary Tree
CF438E The Child and Binary Tree Description 给一个大小为\(n\)的序列\(C\),保证\(C\)中每个元素各不相同,现在你要统计点权全在\(C\)中,且 ...
- CF438E The Child and Binary Tree(生成函数+多项式开根+多项式求逆)
传送门 可以……这很多项式开根模板……而且也完全不知道大佬们怎么把这题的式子推出来的…… 首先,这题需要多项式开根和多项式求逆.多项式求逆看这里->这里,这里讲一讲多项式开根 多项式开方:已知多 ...
- Codeforces 438E The Child and Binary Tree - 生成函数 - 多项式
题目传送门 传送点I 传送点II 传送点III 题目大意 每个点的权值$c\in {c_{1}, c_{2}, \cdots, c_{n}}$,问对于每个$1\leqslant s\leqslant ...
- CF438E The Child and Binary Tree
思路 设F(x)的第x项系数为权值和为x的答案 题目中要求权值必须在集合中出现,这个不好处理,考虑再设一个C,C的第x项如果是1代表x出现在值域里,如果是0,代表x没有出现在值域里,然后由于二叉树可以 ...
- 【CF438E】The Child and Binary Tree(多项式运算,生成函数)
[CF438E]The Child and Binary Tree(多项式运算,生成函数) 题面 有一个大小为\(n\)的集合\(S\) 问所有点权都在集合中,并且点权之和分别为\([0,m]\)的二 ...
- Codeforces 250 E. The Child and Binary Tree [多项式开根 生成函数]
CF Round250 E. The Child and Binary Tree 题意:n种权值集合C, 求点权值和为1...m的二叉树的个数, 形态不同的二叉树不同. 也就是说:不带标号,孩子有序 ...
- [codeforces438E]The Child and Binary Tree
[codeforces438E]The Child and Binary Tree 试题描述 Our child likes computer science very much, especiall ...
随机推荐
- 最全的前端Git基础命令,看完保证你会!
常见信息 master: 默认开发分支 origin:默认远程版本库 Head: 默认开发分支 Head^:Head 的父提交 创建新仓库 git init git init [project-nam ...
- beta阶段测试基本概况报告
文件地址 测试基本信息 Bitmap 测试 ...
- 《Linux内核分析》第六周笔记 进程的描述和进程的创建
进程的描述和进程的创建 一.进程的描述 1.进程描述符task_struct数据结构(一) 操作系统的三大功能:进程管理(核心).内存管理.文件系统. 进程控制块PCB——task_struct(进程 ...
- 业务-----修改Service常用逻辑
注意:修改时唯一属性不能重复 //num==null 时,没有修改Num,不用考虑重复问题.//num!=null 时,修改了num.考虑重复问题 if(!StringUtils.isEmpty(re ...
- Bootstrap @Media分类
手机的屏幕比较小,宽度通常在600像素以下:PC的屏幕宽度,一般都在1000像素以上(目前主流宽度是1366×768)设置相应的min-width和max-width值 所以响应式设计一般对600 ...
- ubuntu安装steam
增加第三方自由库的软件支持 sudo add-apt-repository multiverse 增加更新支持包 sudo add-apt-repository multiverse 安装steam ...
- 关于virtualenv python环境引用 pycharm相关配置的使用讨论
今天总算决定来搞一波以前从来没有弄清楚的环境问题,也觉得是时候弄明白了. 这里先说关于python的环境引用,再谈到virtualenv最后再谈论我使用的pycharm5.0关于是用python环境的 ...
- mysql 分页数据错乱
最近在使用mysql 分页查询数据的时候发现返回的数据与预期的不一样,显示数据重复错乱. 在官方文档 有这样一句话 If multiple rows have identical values in ...
- List泛型集合
List和数组 相同点: 都可以控制元素类型 不同点: List的长度是可变的,所以list比数组更容易掌控 List属性 1.Count 获取集合中实际包含的元素个数 2.Capcity 集合中可以 ...
- pgm13
这部分开始,我们将讨论 learning 相关的内容.PGM 为 frequentist 与 Bayesian 系的 model 提供了同一种语言,对前者来说 learning 就是确定一种对“未知但 ...