题目

首先令\(f_i\)表示权值和为\(i\)的二叉树数量,\(f_0=1\)。

转移为:\(f_k=\sum_{i=0}^n \sum_{j=0}^{k-c_i}f_j f_{k-c_i-j}\)

令多项式\(D=\sum_{i=0}^m [i在c中出现过]x^i\),\(F(x)为f的普通生成函数\),根据转移式发现F其实等于F卷积上F再卷积上D,再加上一个1,因为转移式转移不到\(f_0\)。

所以

\[\begin{align}
F&=F^2D+1\\
DF^2-F+1&=0\\
D^2F^2-DF+D&=0\\
(DF-\frac12)^2+D-\frac14&=0(配方)\\
(DF-\frac12)^2&=\frac14-D\\
DF-\frac12&=\pm \sqrt{\frac14-D}\\
\end{align}
\]

有两解,但是\(f_i\)肯定只有一种可能啊所以肯定有一个解不合法。


当取正号时:

\(DF-\frac12=\sqrt{\frac14-D}\),\(DF=\frac{\sqrt{1-4D}+1}{2}\)

等式右边的常数项为1,但是\(D\)的常数项为0,\(F\)的常数项为1,所以\(DF\)的常数项为0,矛盾。

所以只能取负号。

\[\begin{align}
DF&=\frac{1-\sqrt{1-4D}}{2}\\
F&=\frac{(1-\sqrt{1-4D})(1+\sqrt{1-4D})}{2D(1+\sqrt{1-4D})}\\
F&=\frac{2}{1+\sqrt{1-4D}}\\
\end{align}\\
\]

接下来直接多项式开根+求逆就行了。时间复杂度\(O(n logn)\)。

小知识:多项式能求逆的充要条件是常数项不为0,常数项>0则一定能开根。

点击查看代码
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define pii pair <LL,LL>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back using namespace std; const LL MOD=998244353; LL qpow(LL x,LL a)
{
LL res=x,ret=1;
while(a>0)
{
if((a&1)==1) ret=ret*res%MOD;
a>>=1;
res=res*res%MOD;
}
return ret;
} namespace poly
{
vector <LL> rev;
void ntt(vector <LL> &a,LL G)
{
LL nn=a.size(),gn,g,x,y;vector <LL> tmp=a;
rep(i,nn) a[i]=tmp[rev[i]];
for(int len=1;len<nn;len<<=1)
{
gn=qpow(G,(MOD-1)/(len<<1));
for(int i=0;i<nn;i+=(len<<1))
{
g=1;
for(int j=i;j<i+len;++j,(g*=gn)%=MOD)
{
x=a[j];y=a[j+len]*g%MOD;
a[j]=(x+y)%MOD;a[j+len]=(x-y+MOD)%MOD;
}
}
}
}
vector <LL> convolution(vector <LL> a,vector <LL> b,LL G)
{
LL nn=1,bt=0,sv=a.size()+b.size()-1;while(nn<a.size()+b.size()-1) nn<<=1LL,++bt;
while(a.size()<nn) a.pb(0);while(b.size()<nn) b.pb(0);
rev.clear();
rep(i,nn)
{
rev.pb(0);
rev[i]=(rev[i>>1]>>1)|((i&1)<<(bt-1));
}
ntt(a,G);ntt(b,G);
rep(i,nn) (a[i]*=b[i])%=MOD;
ntt(a,qpow(G,MOD-2));
while(a.size()>sv) a.pop_back();
LL inv=qpow(nn,MOD-2);
rep(i,a.size()) (a[i]*=inv)%=MOD;
return a;
}
vector <LL> inverse(vector <LL> a,LL G)
{
if(a.size()==1) return vector <LL>{qpow(a[0],MOD-2)};
vector <LL> aa=a;while(aa.size()>(a.size()+1)>>1) aa.pop_back();
vector <LL> bb=inverse(aa,G);
LL nn=1,bt=0,sv=a.size();while(nn<a.size()*2) nn<<=1LL,++bt;
while(a.size()<nn) a.pb(0);while(bb.size()<nn) bb.pb(0);
rev.clear();
rep(i,nn)
{
rev.pb(0);
rev[i]=(rev[i>>1]>>1)|((i&1)<<(bt-1));
}
ntt(a,G);ntt(bb,G);
rep(i,nn) a[i]=(2LL-a[i]*bb[i]%MOD+MOD)*bb[i]%MOD;
ntt(a,qpow(G,MOD-2));
while(a.size()>sv) a.pop_back();
LL inv=qpow(nn,MOD-2);
rep(i,a.size()) (a[i]*=inv)%=MOD;
return a;
}
vector <LL> sqrt1(vector <LL> a,LL G)//常数项为1
{
if(a.size()==1) return vector <LL>{1};
vector <LL> aa=a;while(aa.size()>(a.size()+1)>>1) aa.pop_back();
vector <LL> bb=sqrt1(aa,G);while(bb.size()<a.size()) bb.pb(0);
vector <LL> bbb=inverse(bb,G);
LL nn=1,bt=0,sv=a.size();while(nn<a.size()*2) nn<<=1LL,++bt;
while(a.size()<nn) a.pb(0);while(bb.size()<nn) bb.pb(0);while(bbb.size()<nn) bbb.pb(0);
rev.clear();
rep(i,nn)
{
rev.pb(0);
rev[i]=(rev[i>>1]>>1)|((i&1)<<(bt-1));
}
LL mul=qpow(2,MOD-2);
ntt(a,G);ntt(bb,G);ntt(bbb,G);
rep(i,nn) a[i]=mul*(bb[i]+bbb[i]*a[i]%MOD)%MOD;
ntt(a,qpow(G,MOD-2));
while(a.size()>sv) a.pop_back();
LL inv=qpow(nn,MOD-2);
rep(i,a.size()) (a[i]*=inv)%=MOD;
return a;
}
} LL n,m;
vector <LL> c; int main()
{
cin>>n>>m;
rep(i,100001) c.pb(0);
LL x;
rep(i,n)
{
scanf("%lld",&x);
c[x]=1;
}
c[0]=1;
repn(i,100000) c[i]=MOD-c[i]*4LL;
c=poly::sqrt1(c,3);
(c[0]+=1LL)%=MOD;
c=poly::inverse(c,3);
rep(i,c.size()) (c[i]+=c[i])%=MOD;
repn(i,m) printf("%lld\n",c[i]);
return 0;
}

[题解] Codeforces 438 E The Child and Binary Tree DP,多项式,生成函数的更多相关文章

  1. Codeforces 438E The Child and Binary Tree [DP,生成函数,NTT]

    洛谷 Codeforces 思路 看到计数和\(998244353\),可以感觉到这是一个DP+生成函数+NTT的题. 设\(s_i\)表示\(i\)是否在集合中,\(A\)为\(s\)的生成函数,即 ...

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

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

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

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

  4. [bzoj3625][Codeforces 250 E]The Child and Binary Tree(生成函数+多项式运算+FFT)

    3625: [Codeforces Round #250]小朋友和二叉树 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 650  Solved: 28 ...

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

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

  6. [codeforces438E]The Child and Binary Tree

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

  7. [LeetCode]题解(python):114 Flatten Binary Tree to Linked List

    题目来源 https://leetcode.com/problems/flatten-binary-tree-to-linked-list/ Given a binary tree, flatten ...

  8. [LeetCode]题解(python):110 Balanced Binary Tree

    题目来源 https://leetcode.com/problems/balanced-binary-tree/ Given a binary tree, determine if it is hei ...

  9. Codeforces 219D Choosing Capital for Treeland:Tree dp

    题目链接:http://codeforces.com/problemset/problem/219/D 题意: 给你一棵树,n个节点. 树上的边都是有向边,并且不一定是从父亲指向儿子的. 你可以任意翻 ...

随机推荐

  1. 清北学堂 2020 国庆J2考前综合强化 Day2

    目录 1. 题目 T1 一 题目描述 Sol T2 二 题目描述 Sol T3 三 题目描述 Sol T4 四 题目描述 Sol 2. 算法 -- 数据结构 1. 题目 T1 一 题目描述 问题描述 ...

  2. 精心总结十三条建议,帮你创建更合适的MySQL索引

    上篇文章讲到使用MySQL的Explain命令可以分析SQL性能瓶颈,优化SQL查询,以及查看是否用到了索引. 我们都知道创建索引可以提高查询效率,但是具体该怎么创建索引? 哪些字段适合创建索引? 哪 ...

  3. 5.10 NOI 模拟

    最近总是管不住自己摆烂,没法像\(Zwaire\)一样管住自己,摆完之后会有负罪感,一直恶性循环,认识到了这个问题,我希望能逐渐改正(不对,马上放假了,不如摆烂到放假) 话说\(GD,HN\)的老哥都 ...

  4. 《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(11)-Fiddler设置安卓手机抓包,不会可是万万不行的!

    1.简介 Fiddler不但能截获各种浏览器发出的 HTTP 请求,也可以截获各种智能手机发出的HTTP/ HTTPS 请求. Fiddler能截获 Android 和 Windows Phone 等 ...

  5. Flutter 检测报错 Unable to locate Android SDK.

    安装好 Flutter SDK 之后,官方建议使用flutter doctor检查 Flutter SDK 的相关配置信息. 如果 Android Studio 安装 Android SDK 的时候选 ...

  6. 趋势科技 redirfs模块的一个小问题

    最近看的一个问题,消息队列可以创建,但是不能获取属性,也不能发消息,返回错误为:EBADF Bad file descriptor 经过打点,确认走入了这个流程: SYSCALL_DEFINE3(mq ...

  7. RabbitMQ 入门系列:5、基础编码:交换机的进阶介绍及编码方式。

    系列目录 RabbitMQ 入门系列:1.MQ的应用场景的选择与RabbitMQ安装. RabbitMQ 入门系列:2.基础含义:链接.通道.队列.交换机. RabbitMQ 入门系列:3.基础含义: ...

  8. 我用Axure制作了一款火影小游戏 | PM老猫

    Axure不仅仅是一个原型工具,除了原型之外还可以用来制作一些静态网页,这点对于不懂代码或前端的同学来说挺实用.之前整理了一版<Axure函数自查表>,因为感觉内容太多又对前端样式及脚本感 ...

  9. springboot配置(yami配置文件,JSR303数据校验,多环境配置)

    yami配置文件 YAML是 "YAML Ain't a Markup Language" (YAML不是一种标记语言)的递归缩写.在开发的这种语言时,YAML 的意思其实是:&q ...

  10. (最简单详细)IronPython下载、安装及简单使用

    说实话,对于我这种小白,在网上找个IronPython找的很费劲,学会操作之后,直接整个随笔,供新手参考.前提是现在你应该有VS了 (1)找到IronPython的网站 很多人肯定就按照习惯搜索,Ir ...