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 ...
随机推荐
- hadoop_spark伪分布式实验环境搭建和运行实例详细教程
hadoop+spark伪分布式环境搭建 安装须知 单机模式(standalone): 该模式是Hadoop的默认模式.这种模式在一台单机上运行,没有分布式文件系统,而是直接读写本地操作系统的文件系统 ...
- python中使用pymongo操作mongo
MongoDB是由C++语言编写的非关系型数据库,是一个基于分布式文件存储的开源数据库系统,其内容存储形式类似JSON对象,它的字段值可以包含其他文档.数组及文档数组,非常灵活.在这一节中,我们就来看 ...
- (理论篇)从基础文件IO说起虚拟内存,内存文件映射,零拷贝
为了快速构建项目,使用高性能框架是我的职责,但若不去深究底层的细节会让我失去对技术的热爱. 探究的过程是痛苦并激动的,痛苦在于完全理解甚至要十天半月甚至没有机会去应用,激动在于技术的相同性,新的框架不 ...
- C. A Mist of Florescence
链接 [http://codeforces.com/contest/989/problem/C] 题意 给定A B C D四个字符个数,让你构造一个矩阵使得他们的个数恰好那么多,联通块算一块 分析 构 ...
- 【Beta阶段】第十次Scrum Meeting!!!
每日任务内容: 本次会议为第十次Scrum Meeting会议~ 本次会议为团队Beta阶段的最后一次会议!! 队员 今日完成任务 刘乾 #136(完成一半,今晨发布) 团队博客撰写 https:// ...
- ml-模型评估与选择
1.基本概念 错误率E=分类错误的样本数a/总样本数m:精度=1-a/m 经验误差/训练误差:在训练集上产生的 泛化误差:在测试集上产生的=====>要把这个泛化误差降到最小化. 2.评估方法 ...
- action中session的存取
存 ActionContext.getContext().getSession().put("teacherlist", teacherlist); 取 teacherlist=( ...
- HDU 1236 排名(Microsoft_zzt)
http://acm.hdu.edu.cn/showproblem.php?pid=1236 Problem Description 今天的上机考试虽然有实时的Ranklist,但上面的排名只是根据完 ...
- php中获取数据 php://input、$_POST与$GLOBALS['HTTP_RAW_POST_DATA']三者的区别
$_POST 只有Coentent-Type的值为application/x-www.form-urlencoded和multipart/form-data两种类型时,$_POST才能获取到数据. $ ...
- 转帖 云和恩墨 http://www.eygle.com/archives/2015/06/sql_version_count.html
SQL多版本控制 - _CURSOR_OBSOLETE_THRESHOLD 作者:eygle |English [转载时请标明出处和作者信息]|[恩墨学院 OCM培训传DBA成功之道]链接:htt ...