首先,我们构造一个函数$G(x)$,若存在$k∈C$,则$[x^k]G(x)=1$。

不妨设$F(x)$为最终答案的生成函数,则$[x^n]F(x)$即为权值为$n$的神犇二叉树个数。

不难推导出,$[x^n]F(x)=\sum_{i=0}^{n}[x^i]G(x)\sum_{j=0}^{n-i}[x^j]F(j)\times [x^{n-j-i}]F(n-j-i)$。

(这个式子的意思就是说,不妨设当前根节点的权值为i,然后枚举左右两个子树的权值)

这个式子显然可以通过动规的方式去推,从而得出答案,优化后的时间复杂度是$O(n^2)$的,显然不行。

我们对式子进行化简,考虑到$[x^0]F(x)=1$,那么$F(x)=G(x)\times F^2(x)+1$。

通过移项,得到$G\times F^2-F+1=0$,是一个关于$F$的一元二次方程。

由于多项式$G(x)$是已知的,那么我们就可以通过求根公式解出$F(x)$。

套入求根公式,得到$F(x)=\frac{1±\sqrt{1-4G}}{2G}$。

考虑到$F(0)=1$,$G(0)=0$,那么$F(x)=\frac{1-\sqrt{1-4G}}{2G}$

分子分母同时乘上$1+\sqrt{1-4G}$,化简得到$F(x)=\frac{2}{1+\sqrt{1-4G}}$。

然后就是多项式开根+多项式求逆了。

#include<bits/stdc++.h>
#define M (1<<18)
#define L long long
#define MOD 998244353
#define inv2 499122177
#define G 3
using namespace std; L pow_mod(L x,L k){
L ans=;
while(k){
if(k&) ans=ans*x%MOD;
x=x*x%MOD; k>>=;
}
return ans;
} void change(L a[],int n){
for(int i=,j=;i<n-;i++){
if(i<j) swap(a[i],a[j]);
int k=n>>;
while(j>=k) j-=k,k>>=;
j+=k;
}
}
void NTT(L a[],int n,int on){
change(a,n);
for(int h=;h<=n;h<<=){
L wn=pow_mod(G,(MOD-)/h);
for(int j=;j<n;j+=h){
L w=;
for(int k=j;k<j+(h>>);k++){
L u=a[k],t=w*a[k+(h>>)]%MOD;
a[k]=(u+t)%MOD;
a[k+(h>>)]=(u-t+MOD)%MOD;
w=w*wn%MOD;
}
}
}
if(on==-){
L inv=pow_mod(n,MOD-);
for(int i=;i<n;i++) a[i]=a[i]*inv%MOD;
reverse(a+,a+n);
}
} void getinv(L a[],L b[],int n){
if(n==){b[]=pow_mod(a[],MOD-); return;}
static L c[M],d[M];
memset(c,,n<<); memset(d,,n<<);
getinv(a,c,n>>);
for(int i=;i<n;i++) d[i]=a[i];
NTT(d,n<<,); NTT(c,n<<,);
for(int i=;i<(n<<);i++) b[i]=(*c[i]-d[i]*c[i]%MOD*c[i]%MOD+MOD)%MOD;
NTT(b,n<<,-);
for(int i=;i<n;i++) b[n+i]=;
} void sqrt(L a[],L b[],int n){
if(n==) return void(b[]=);
sqrt(a,b,n>>);
static L invb[M],d[M];
memset(invb,,M<<); memset(d,,M<<);
getinv(b,invb,n);
for(int i=;i<n;i++) d[i]=a[i];
NTT(b,n<<,); NTT(d,n<<,); NTT(invb,n<<,);
for(int i=;i<(n<<);i++) b[i]=inv2*(b[i]+d[i]*invb[i]%MOD)%MOD;
NTT(b,n<<,-);
for(int i=;i<n;i++) b[i+n]=;
}
L a[M]={},b[M]={};
int main(){
int n,m; scanf("%d%d",&n,&m);
int nn=; while(nn<=m) nn<<=;
a[]=;
for(int i=;i<=n;i++){
int x; scanf("%d",&x);
if(x<=m) a[x]=(a[x]-+MOD)%MOD;
}
sqrt(a,b,nn); b[]=(b[]+)%MOD;
memset(a,,nn<<);
getinv(b,a,nn);
for(int i=;i<=m;i++) printf("%lld\n",a[i]*%MOD);
}

【BZOJ3625】【codeforces438E】小朋友和二叉树 生成函数+多项式求逆+多项式开根的更多相关文章

  1. FFT模板 生成函数 原根 多项式求逆 多项式开根

    FFT #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> ...

  2. 2019.01.01 bzoj3625:小朋友和二叉树(生成函数+多项式求逆+多项式开方)

    传送门 codeforces传送门codeforces传送门codeforces传送门 生成函数好题. 卡场差评至今未过 题意简述:nnn个点的二叉树,每个点的权值KaTeX parse error: ...

  3. [Codeforces438E][bzoj3625] 小朋友和二叉树 [多项式求逆+多项式开根]

    题面 传送门 思路 首先,我们把这个输入的点的生成函数搞出来: $C=\sum_{i=0}^{lim}s_ix^i$ 其中$lim$为集合里面出现过的最大的数,$s_i$表示大小为$i$的数是否出现过 ...

  4. bzoj 3625小朋友和二叉树 多项式求逆+多项式开根 好题

    题目大意 给定n种权值 给定m \(F_i表示权值和为i的二叉树个数\) 求\(F_1,F_2...F_m\) 分析 安利博客 \(F_d=F_L*F_R*C_{mid},L+mid+R=d\) \( ...

  5. NTT+多项式求逆+多项式开方(BZOJ3625)

    定义多项式$h(x)$的每一项系数$h_i$,为i在c[1]~c[n]中的出现次数. 定义多项式$f(x)$的每一项系数$f_i$,为权值为i的方案数. 通过简单的分析我们可以发现:$f(x)=\fr ...

  6. 【BZOJ3456】轩辕朗的城市规划 无向连通图计数 CDQ分治 FFT 多项式求逆 多项式ln

    题解 分治FFT 设\(f_i\)为\(i\)个点组成的无向图个数,\(g_i\)为\(i\)个点组成的无向连通图个数 经过简单的推导(枚举\(1\)所在的连通块大小),有: \[ f_i=2^{\f ...

  7. bzoj 3456 城市规划——分治FFT / 多项式求逆 / 多项式求ln

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3456 分治FFT: 设 dp[ i ] 表示 i 个点时连通的方案数. 考虑算补集:连通的方 ...

  8. P6295-有标号 DAG 计数【多项式求逆,多项式ln】

    正题 题目链接:https://www.luogu.com.cn/problem/P6295 题目大意 求所有\(n\)个点的弱联通\(DAG\)数量. \(1\leq n\leq 10^5\) 解题 ...

  9. 【learning】多项式相关(求逆、开根、除法、取模)

    (首先要%miskcoo,这位dalao写的博客(这里)实在是太强啦qwq大部分多项式相关的知识都是从这位dalao博客里面学的,下面这篇东西是自己对其博客学习后的一些总结和想法,大部分是按照其博客里 ...

随机推荐

  1. Win7 SP1 提示ADO的问题

    需要安装  Windows6.1-KB2640696-v3-x64.msu 这个Pack

  2. 测试setsockopt设置超时是否生效代码

    // 测试setsockopt设置超时是否生效代码 #include <arpa/inet.h> #include <netinet/in.h> #include <st ...

  3. CreateDialog()与CreateDialogIndrect()

    CreateDialog() 概述 函数功能:CreateDialog宏从一个对话框模板资源创建一个无模式的对话框,CreateDiaog宏使用CreateDialogParam函数. 函数原型:HW ...

  4. HDU6029 Happy Necklace 2017-05-07 19:11 45人阅读 评论(0) 收藏

    Happy Necklace                                                                           Time Limit: ...

  5. linux环境下(非UI操作)所有软件的安装与卸载总结

    UI界面的软件管理 linux下的软件一般都是经过压缩的,主要的格式有这几种:rpm.tar.tar.gz.tgz等.所以首先拿到软件后第一件事就是解压缩. 在xwindow下以rpm格式的软件安装比 ...

  6. maven镜像

    使用maven管理项目,下载依赖jar包的时候,经常会下载很慢,但是如果使用镜像的话,速度超级快~~只要在.m2/setting.xml文件中设置镜像就可以啦~ 本文来自https://yq.aliy ...

  7. 【python】基础入门

    1.正则表达式 import re sql="aaa$1bbbbccccc$2sdfsd gps_install_note_id =$3;" regexp=r'\$\d+' # 编 ...

  8. Intellij Idea 14编译golang 插件

    最近项目实在太赶了,很久没有写过博文了. 公司新配了一台笔记本电脑,原装win8的.于是又从linux回到了windows.不想用win命令行来搞go了,win下太折腾了.还是用一直使用的idea. ...

  9. 在每页(分页)报表中重复显示标题 - SQL Server Reporting Service (SSRS)

    问题描述 TFS系统提供多种报表,有图表(Chart).Web面板(Dashboard).SharePoint面板.Excel报表,SQL Server Reporting Serivce(SSRS) ...

  10. leetcode 搜索插入位置

    给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引.如果目标值不存在于数组中,返回它将会被按顺序插入的位置. 你可以假设数组中无重复元素. 示例 1: 输入: [1,3,5,6], 5 输 ...