题目描述:

bzoj

luogu

题解:

生成函数ntt。

显然这种二叉树应该暴力薅掉树根然后分裂成两棵子树。

所以$f(x)= \sum_{i \in c} \sum _{j=0}^{x-c} f(i)*f(x-i-j)$

这是个不好看的卷积。

所以我们再引入$c$的生成函数$G$,那么有$$F(x)=1+G(x)*F(x)*F(x)$$

注意常数项,因为正常$f(0)=1$但是$G(0)=0$,所以要人为配常数。

然后$F= \frac{1 \pm \sqrt{1-4G}} {2G} = \frac{2}{1 \pm \sqrt{1-4G}}$

还是因为系数,正负号只能取正。

bz严重卡常:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = ;
const int MOD = ;
const int inv_2 = ((MOD+)>>);
template<typename T>
inline void read(T&x)
{
T f = ,c = ;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){c=c*+ch-'';ch=getchar();}
x = f*c;
}
inline void Mod(unsigned int&x){if(x>=MOD)x-=MOD;}
inline unsigned int fastpow(unsigned int x,int y)
{
int ret = ;
while(y)
{
if(y&)ret=1ll*ret*x%MOD;
x=1ll*x*x%MOD;y>>=;
}
return ret;
}
int inv(const unsigned int x){return fastpow(x,MOD-);}
int to[N],lim,L,LL[N],n,m;
inline void init(const int len)
{
lim=LL[]=;
while(lim<=len)lim<<=,LL[lim<<]=LL[lim]+;
}
unsigned int W[N],INV;
inline void get_lim(const int len)
{
lim = len,L = LL[len];
for(register int i=;i<lim;++i)to[i]=((to[i>>]>>)|((i&)<<(L-)));
INV = inv(len);
for(register int i=;i<lim;i<<=)W[i]=fastpow(,(MOD-)/(i<<));
}
inline void ntt(unsigned int*a,const int len,const int k)
{
for(register int i=;i<len;++i)
if(i<to[i])swap(a[i],a[to[i]]);
for(register int i=;i<len;i<<=)
{
unsigned int w0 = W[i];
for(register int j=;j<len;j+=(i<<))
{
unsigned int w = ;
for(register int o=;o<i;++o,w=1ll*w*w0%MOD)
{
unsigned int w1 = a[j+o],w2 = 1ll*a[j+o+i]*w%MOD;
Mod(a[j+o]=w1+w2);
Mod(a[j+o+i]=w1+MOD-w2);
}
}
}
if(k==-)
{
for(register int i=;i<len>>;++i)swap(a[i],a[len-i]);
for(register int i=;i<len;++i)a[i]=1ll*a[i]*INV%MOD;
}
}
unsigned int a[N],b[N],c[N];
void mul(unsigned int*F,unsigned int*G,unsigned int*H,const int len)
{
get_lim(len<<);
for(register int i=;i<lim;++i)a[i]=b[i]=;
for(register int i=;i<len;++i)a[i]=F[i],b[i]=G[i];
ntt(a,lim,),ntt(b,lim,);
for(register int i=;i<lim;++i)c[i]=1ll*a[i]*b[i]%MOD;
ntt(c,lim,-);
for(register int i=;i<lim;++i)H[i]=c[i];
}
unsigned int T[N];
void get_inv(unsigned int*F,unsigned int*G,const int len)
{
if(len==){G[]=inv(F[]),G[]=;return ;}
get_inv(F,G,len>>);
get_lim(len<<);for(register int i=;i<lim;++i)a[i]=b[i]=;
for(register int i=;i<len;++i)a[i]=F[i];for(register int i=;i<(len>>);++i)b[i]=G[i];
ntt(a,lim,),ntt(b,lim,);for(register int i=;i<lim;++i)c[i]=1ll*a[i]*b[i]%MOD*b[i]%MOD;ntt(c,lim,-);
for(register int i=;i<len;++i)G[i]=(2ll*G[i]+MOD-c[i])%MOD,G[i+len]=;
}
unsigned int H[N];
void get_sqrt(unsigned int*F,unsigned int*G,const int len)
{
if(len==){G[]=;return ;}
get_sqrt(F,G,len>>);get_inv(G,H,len);
mul(G,G,T,len);for(register int i=;i<len;++i)T[i]=1ll*(T[i]+F[i])*inv_2%MOD;
mul(H,T,G,len);for(register int i=len;i<(len<<);++i)G[i]=;
}
unsigned int F[N],G[N],S[N];
int main()
{
// freopen("tt.in","r",stdin);
read(n),read(m);
init(m);int c,mx = lim;
for(register int i=;i<=n;++i)
read(c),G[c]=MOD-;
G[]++;
get_sqrt(G,S,mx);
S[]++;
for(register int i=;i<mx;++i)S[i]=1ll*S[i]*inv_2%MOD;
get_inv(S,F,mx);
for(register int i=;i<=m;++i)
printf("%u\n",F[i]);
return ;
}

[Codeforces Round #250]小朋友和二叉树的更多相关文章

  1. BZOJ 3625: [Codeforces Round #250]小朋友和二叉树

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

  2. BZOJ3625: [Codeforces Round #250]小朋友和二叉树

    Description 我们的小朋友很喜欢计算机科学,而且尤其喜欢二叉树.考虑一个含有n个互异正整数的序列c[1],c[2],...,c[n].如果一棵带点权的有根二叉树满足其所有顶点的权值都在集合{ ...

  3. BZOJ3625 [Codeforces Round #250]小朋友和二叉树(生成函数+多项式开根)

    设f(n)为权值为n的神犇二叉树个数.考虑如何递推求这个东西. 套路地枚举根节点的左右子树.则f(n)=Σf(i)f(n-i-cj),cj即根的权值.卷积的形式,cj也可以通过卷上一个多项式枚举.可以 ...

  4. BZOJ 3625 [Codeforces Round #250]小朋友和二叉树 ——NTT 多项式求逆 多项式开根

    生成函数又有奇妙的性质. $F(x)=C(x)*F(x)*F(x)+1$ 然后大力解方程,得到一个带根号的式子. 多项式开根有解只与常数项有关. 发现两个解只有一个是成立的. 然后多项式开根.求逆. ...

  5. bzoj 3625: [Codeforces Round #250]小朋友和二叉树【NTT+多项式开根求逆】

    参考:https://www.cnblogs.com/2016gdgzoi509/p/8999460.html 列出生成函数方程,g(x)是价值x的个数 \[ f(x)=g(x)*f^2(x)+1 \ ...

  6. [BZOJ3625][Codeforces Round #250]小朋友和二叉树 多项式开根+求逆

    https://www.lydsy.com/JudgeOnline/problem.php?id=3625 愉快地列式子.设\(F[i]\)表示权值为\(i\) 的子树的方案数,\(A[i]\)为\( ...

  7. Codeforces Round#250 D. The Child and Zoo(并差集)

    题目链接:http://codeforces.com/problemset/problem/437/D 思路:并差集应用,先对所有的边从大到小排序,然后枚举边的时候,如果某条边的两个顶点不在同一个集合 ...

  8. Codeforces Round #250 (Div. 2)A(英语学习)

    链接:http://codeforces.com/contest/437/problem/A A. The Child and Homework time limit per test 1 secon ...

  9. Codeforces Round #250 (Div. 1) D. The Child and Sequence (线段树)

    题目链接:http://codeforces.com/problemset/problem/438/D 给你n个数,m个操作,1操作是查询l到r之间的和,2操作是将l到r之间大于等于x的数xor于x, ...

随机推荐

  1. Swing 实现的Gui链表

    https://gitee.com/dgwcode/MyJavaCode -Freight类可以实现的功能·构造方法:初始空车厢有5个·装货:当运往某地点的货物大于等于4个的时候,如果有空车箱,则先占 ...

  2. Django配置文件解释

    """Django settings for first project. Generated by 'django-admin startproject' using ...

  3. angular4和asp.net core 2 web api

    angular4和asp.net core 2 web api 这是一篇学习笔记. angular 5 正式版都快出了, 不过主要是性能升级. 我认为angular 4还是很适合企业的, 就像.net ...

  4. PartTime_一些网站

    1. http://www.sxsoft.com/ 貌似 搜搜"破解",无符合条件的结果 http://www.taskcity.com/ "智城",貌似 符合 ...

  5. aix OPATH ISSUE

    issue 1: OPatch cannot find a valid oraInst.loc file to locate Central Inventory (OPatch failed with ...

  6. swjtu oj Paint Box 第二类斯特林数

    http://swjtuoj.cn/problem/2382/ 题目的难点在于,用k种颜色,去染n个盒子,并且一定要用完这k种颜色,并且相邻的格子不能有相同的颜色, 打了个表发现,这个数是s(n, k ...

  7. 数据库操作语法错误(SQL syntax error)之两步走

    今天在做web应用操作数据库时出现了语法错误,提示的是在“xxxxxxx”附近出现了语法错误:CODE:Error: You have an error in your SQL syntax. Che ...

  8. OpenCV ——IplImage应用解析

    由于OpenCV主要针对的是计算机视觉方面的处理,因此在函数库中,最重要的结构体是IplImage结构.IplImage结构来源于Intel的另外一个函数库Intel Image Processing ...

  9. 获取spring里的bean

    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring. ...

  10. 疯狂使用 leancloud (投稿文章)

    疯狂使用 leancloud 本文章是投稿文章,已在 leancloud 微信公众号发表. 这里是原文,内容有调整. 3年,从工程师到创始人 觉得不错可以点这里进行 leancloud 注册 项目背景 ...