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 ...
随机推荐
- Microsoft Visual Studio 2013安装及试用
我是在网上下载的vs2013版的安装包,下载的是压缩文件,解压后是2.86GB.安装包下载完成后我们就可以进入安装了. 同时建议最好在互联网连接的情况下安装. 打开下载好的文件,我们要选择.exe可执 ...
- 【实践报告】Linux实践三
Linux实践——程序破解 一.掌握NOP.JNE.JE.JMP.CMP汇编指令的机器码 NOP:NOP指令即“空指令”.执行到NOP指令时,CPU什么也不做,仅仅当做一个指令执行过去并继续执行NOP ...
- Linux内核分析作业五
扒开系统调用的三层皮(下) 给MenuOS增加time和time-asm命令 步骤 rm menu -rf //强制删除 git clone http://github.com/menging/men ...
- Linux内核第七节 20135332武西垚
预处理.编译.链接和目标文件的格式 可执行程序是怎么得来的 以C语言为例,c代码经过编译器的预处理,编译成汇编代码,由汇编器编译成目标代码,再链接成可执行文件,由操作系统加载到cpu里来执行. (截图 ...
- windows、ubuntu、centos7下mysql 的安装与使用
一.windows 及ubuntu下安装 windows可以傻瓜式安装,另一种空闲了下来写,也不麻烦 ubuntu: apt-get install mysql 强烈推荐使用ubuntu从这儿就很方便 ...
- 软件工程(GZSD2015) 第三次作业提交进度
第三次作业题目请查看这里:软件工程(GZSD2015)第三次作业 开始进入第三次作业提交进度记录中,童鞋们,虚位以待哈... 2015年4月19号 徐镇.尚清丽,C语言 2015年4月21号 毛涛.徐 ...
- 福州大学软件工程1816 | W班 作业成绩排名汇总
评分链接 第一次作业--准备篇 第二次作业--个人项目实战 第三次作业--原型设计(结对第一次) 第四次作业--团队展示(团队) 第五次作业--项目选题报告(团队) 第六次作业--结对第2次作业--W ...
- Maven -Maven配置tomcat插件 两种
Maven Tomcat插件现在主要有两个版本,tomcat-maven-plugin和tomcat7-maven-plugin,使用方式基本相同. tomcat-maven-plugin 插件官网: ...
- 自己实现数据结构系列一---ArrayList
1.先上代码: public class ArrayList<E> { private E[] data; private int size; /** * 构造方法,初始化容量capaci ...
- Glace:generator-jhipster, adding User entity enhancement management
https://github.com/jhipster/generator-jhipster/issues/2538 jhipster,很好用的开发工具.国外知名度高,国内未普及,国外大公司在用. j ...