正题

题目链接:https://www.luogu.com.cn/problem/CF438E


题目大意

每个节点有\(n\)个权值可以选择,对于\(1\sim m\)中的每个数字\(k\),求权值和为\(k\)的二叉树个数。


解题思路

设\(f_n\)表示权值和为\(n\)的方案数,\(g_n\)表示\(n\)这个权值是否可用。

那么我们对于一个\(n\)的转移,可以枚举根节点的权值,然后再用\(f\)去计算子节点的权值,具体的式子是

\[f_n=\sum_{w=1}^ng_w\sum_{i=0}^{n-w}f_if_{n-w-i}
\]

会发现这个三个数的下标和就是\(n\),这其实一个大卷积,设多项式\(F[x]=f_x\)和\(G[x]=g_x\)。那么根据上面式子就有

\[F=F^2G+1
\]

(加1是因为\(f_0=1\),然后可以解出式子)

\[F=\frac{1\pm \sqrt{1-4G}}{2G}
\]

这里的\(\pm\)我们取负号,因为取正号时不满足收敛性。

当然我也不知道怎么判正负,但是这题发现\(F[0]=1\)但是\(G[0]=1\)。又有\(2GF=1\pm\sqrt{1-4G}\),显然有\((2GF)[0]=0\)。但是如果取正号,那么\((1+\sqrt{1-4G})[0]\geq1\),所以显然不可能,只能取负。

然后可以直接上多项式开根和求逆做?发现\(G[0]=0\)不能求逆,只好再化一下式子变成

\[F=\frac{2}{1+\sqrt{1-4G}}
\]

时间复杂度\(O(n\log n)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=8e5+10,P=998244353,inv2=(P+1)/2;
ll n,m,a[N],b[N];
ll power(ll x,ll b){
ll ans=1;
while(b){
if(b&1)ans=ans*x%P;
x=x*x%P;b>>=1;
}
return ans;
}
namespace Poly{
ll n,t1[N],t2[N],t3[N],t4[N],r[N];
void GetL(ll l){
n=1;while(n<=l)n<<=1;
for(ll i=0;i<n;i++)
r[i]=(r[i>>1]>>1)|((i&1)?(n>>1):0);
return;
}
void NTT(ll *f,ll op){
for(ll i=0;i<n;i++)
if(i<r[i])swap(f[i],f[r[i]]);
for(ll p=2;p<=n;p<<=1){
ll len=p>>1,tmp=power(3,(P-1)/p);
if(op==-1)tmp=power(tmp,P-2);
for(ll k=0;k<n;k+=p){
ll buf=1;
for(ll i=k;i<k+len;i++){
ll tt=f[i+len]*buf%P;
f[i+len]=(f[i]-tt+P)%P;
f[i]=(f[i]+tt)%P;
buf=buf*tmp%P;
}
}
}
if(op==-1){
ll invn=power(n,P-2);
for(ll i=0;i<n;i++)
f[i]=f[i]*invn%P;
}
return;
}
void GetInv(ll *f,ll *g,ll m){
if(m==1){g[0]=power(f[0],P-2);return;}
GetInv(f,g,m>>1);GetL(m);
for(ll i=0;i<m;i++)t1[i]=f[i],t2[i]=g[i];
for(ll i=m;i<n;i++)t1[i]=t2[i]=0;
NTT(t1,1);NTT(t2,1);
for(ll i=0;i<n;i++)t1[i]=t1[i]*t2[i]%P*t2[i]%P;
NTT(t1,-1);
for(ll i=0;i<m;i++)g[i]=(2*g[i]-t1[i]+P)%P;
return;
}
void GetSqrt(ll *f,ll *g,ll m){
if(m==1){g[0]=1;return;}
GetSqrt(f,g,m>>1);
for(ll i=0;i<m;i++)t3[i]=0;
GetInv(g,t3,m);GetL(m<<1);
for(ll i=0;i<m;i++)t4[i]=f[i];
for(ll i=m;i<n;i++)t3[i]=t4[i]=0;
NTT(t3,1);NTT(t4,1);
for(ll i=0;i<n;i++)t3[i]=t3[i]*t4[i]%P;
NTT(t3,-1);
for(ll i=0;i<m;i++)
g[i]=(g[i]+t3[i])*inv2%P;
return;
}
}
signed main()
{
scanf("%lld%lld",&n,&m);
for(ll i=0;i<n;i++){
ll x;
scanf("%lld",&x);
if(x>m)continue;
a[x]=P-4;
}
ll l=1;a[0]++;
while(l<=m)l<<=1;
Poly::GetSqrt(a,b,l);
memset(a,0,sizeof(a));
b[0]++;Poly::GetInv(b,a,l);
for(ll i=1;i<=m;i++)
printf("%lld\n",a[i]*2%P);
return 0;
}

CF438E-The Child and Binary Tree【生成函数】的更多相关文章

  1. 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( ...

  2. cf438E. The Child and Binary Tree(生成函数 多项式开根 多项式求逆)

    题意 链接 Sol 生成函数博大精深Orz 我们设\(f(i)\)表示权值为\(i\)的二叉树数量,转移的时候可以枚举一下根节点 \(f(n) = \sum_{w \in C_1 \dots C_n} ...

  3. [题解] CF438E The Child and Binary Tree

    CF438E The Child and Binary Tree Description 给一个大小为\(n\)的序列\(C\),保证\(C\)中每个元素各不相同,现在你要统计点权全在\(C\)中,且 ...

  4. CF438E The Child and Binary Tree(生成函数,NTT)

    题目链接:洛谷 CF原网 题目大意:有 $n$ 个互不相同的正整数 $c_i$.问对于每一个 $1\le i\le m$,有多少个不同形态(考虑结构和点权)的二叉树满足每个点权都在 $c$ 中出现过, ...

  5. CF438E The Child and Binary Tree(生成函数+多项式开根+多项式求逆)

    传送门 可以……这很多项式开根模板……而且也完全不知道大佬们怎么把这题的式子推出来的…… 首先,这题需要多项式开根和多项式求逆.多项式求逆看这里->这里,这里讲一讲多项式开根 多项式开方:已知多 ...

  6. Codeforces 438E The Child and Binary Tree - 生成函数 - 多项式

    题目传送门 传送点I 传送点II 传送点III 题目大意 每个点的权值$c\in {c_{1}, c_{2}, \cdots, c_{n}}$,问对于每个$1\leqslant s\leqslant ...

  7. CF438E The Child and Binary Tree

    思路 设F(x)的第x项系数为权值和为x的答案 题目中要求权值必须在集合中出现,这个不好处理,考虑再设一个C,C的第x项如果是1代表x出现在值域里,如果是0,代表x没有出现在值域里,然后由于二叉树可以 ...

  8. 【CF438E】The Child and Binary Tree(多项式运算,生成函数)

    [CF438E]The Child and Binary Tree(多项式运算,生成函数) 题面 有一个大小为\(n\)的集合\(S\) 问所有点权都在集合中,并且点权之和分别为\([0,m]\)的二 ...

  9. Codeforces 250 E. The Child and Binary Tree [多项式开根 生成函数]

    CF Round250 E. The Child and Binary Tree 题意:n种权值集合C, 求点权值和为1...m的二叉树的个数, 形态不同的二叉树不同. 也就是说:不带标号,孩子有序 ...

  10. [codeforces438E]The Child and Binary Tree

    [codeforces438E]The Child and Binary Tree 试题描述 Our child likes computer science very much, especiall ...

随机推荐

  1. WPF中实现动画的几种效果(最基础方式)

    参考网址:https://blog.csdn.net/qq_45096273/article/details/106256397 在动画之前我们先了解一下几个声明式动画中常用的元素: 一.Storyb ...

  2. Spring boot集成Redis实现sessions共享时,sessions过期时间问题分析

    Springboot鼓励零配置的方式,帮你做好大部分重复劳动的事,好到不能再好:具体的Redis安装方法和Springboot集成Redis方法,可以去搜索相关文章或参考该文章http://www.c ...

  3. sql 中的with 语句使用

    一直以来都很少使用sql中的with语句,但是看到了一篇文章中关于with的使用,它的确蛮好用,希望以后记得使用这个语句.一.with 的用法With alias_name as (select1)[ ...

  4. springboot与通用mapper的整合

    找到springboot工程下的pom.xml文件,导入如下的依赖jar包 <!--配置通用Mapper start--> <dependency> <groupId&g ...

  5. Linux中的静态库与动态库

    什么是库文件? 库文件是事先编译好的方法的合集.比如:我们提前写好一些数据公式的实现,将其打包成库文件,以后使用只需要库文件就可以,不需要重新编写. Linux系统中: 1.静态库的扩展名为.a:2. ...

  6. springboot&&springcloud知识点

    spring cloud 常见面试题: A.https://blog.csdn.net/panhaigang123/article/details/79587612 B.https://blog.cs ...

  7. 不同的 count 用法

    不同的 count 用法效率:在 select count(?) from t 这样的查询语句里面, count(*).count(主键 id).count(字段) 和 count(1) 等不同用法的 ...

  8. Node.js & Kubernetes Graceful Shutdown

    k8s-graceful-shutdown:该库提供了使用 Kubernetes 实现 Graceful Shutdown(优雅退出) Node.js App 的资源. 问题描述 在 kubernet ...

  9. rabbitMq队列长度限制

    x-max-length:队列最大容纳消息条数 大于设置条数的时候会把,消息队列头部(先进入消息)的消息移除 x-max-length-bytes:队列最大容量消息内存容量服务端限流内存控制流量:40 ...

  10. go-Gorm

    软删除 如果模型中有 DeletedAt 字段,它将自动拥有软删除的能力!当执行删除操作时,数据并不会永久的从数据库中删除,而是将 DeletedAt 的值更新为当前时间.