参考:https://www.cnblogs.com/2016gdgzoi509/p/8999460.html

列出生成函数方程,g(x)是价值x的个数

\[f(x)=g(x)*f^2(x)+1
\]

+1是f[0]=1

根据公式解出

\[f(x)=\frac{1+(-)\sqrt{1-4*g(x)}}{2*g(x)}
\]

舍去+的答案,分式上下同乘\( 1-\sqrt{1-4*g(x)} \)

\[f(x)=\frac{2}{1+\sqrt{1-4*g(x)}}
\]

然后套多项式开跟和求逆的板子即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int N=500005,mod=998244353,inv2=499122177;
int n,m,bt,lm,re[N],a[N],b[N],c[N],t[N];//,aa[N],bb[N],cc[N];
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
int ksm(int a,int b)
{
int r=1;
while(b)
{
if(b&1)
r=1ll*r*a%mod;
a=1ll*a*a%mod;
b>>=1;
}
return r;
}
void dft(int a[],int f,int lm)
{
// for(int i=0;i<lm;i++)
// cerr<<a[i]<<" ";cerr<<endl;
// bt=log2(lm);//cerr<<" "<<lm<<" "<<bt<<endl;
// for(int i=0;i<lm;i++)
// re[i]=(re[i>>1]>>1)|((i&1)<<(bt-1));
for(int i=0;i<lm;i++)
if(i<re[i])
swap(a[i],a[re[i]]);
for(int i=1;i<lm;i<<=1)
{
int wi=ksm(3,(mod-1)/(i*2));
if(f==-1)
wi=ksm(wi,mod-2);
for(int k=0;k<lm;k+=(i<<1))
{
int w=1,x,y;
for(int j=0;j<i;j++)
{
x=a[j+k],y=1ll*w*a[i+j+k]%mod;
a[j+k]=(x+y)%mod,a[i+j+k]=(x-y+mod)%mod;
w=1ll*w*wi%mod;
}
}
}
if(f==-1)
{
int ni=ksm(lm,mod-2);
for(int i=0;i<lm;i++)
a[i]=1ll*a[i]*ni%mod;
}
// for(int i=0;i<lm;i++)
// cerr<<a[i]<<" ";cerr<<endl<<endl;;
}
void qiuni(int len)
{
if(len==1)
{
c[0]=ksm(b[0],mod-2);
return;
}
qiuni(len>>1);
memcpy(t,b,sizeof(int)*len);
memset(t+len,0,sizeof(int)*len);
int bt=-1,lm=1;
while(lm<len<<1)
lm<<=1,bt++;
for(int i=0;i<lm;i++)
re[i]=(re[i>>1]>>1)|((i&1)<<bt);
dft(t,1,lm);
dft(c,1,lm);
for(int i=0;i<lm;i++)
c[i]=1ll*c[i]*(2-1ll*t[i]*c[i]%mod+mod)%mod;
dft(c,-1,lm);
memset(c+len,0,sizeof(int)*len);
}
void kaigen(int len)
{
if(len==1)
{
b[0]=1;
return;
}
kaigen(len>>1);
memset(c,0,sizeof(int)*len);
qiuni(len);
memcpy(t,a,sizeof(int)*len);
memset(t+len,0,sizeof(int)*len);
int bt=-1,lm=1;
while(lm<len<<1)
lm<<=1,bt++;
for(int i=0;i<lm;i++)
re[i]=(re[i>>1]>>1)|((i&1)<<bt);
dft(t,1,lm);
dft(b,1,lm);
dft(c,1,lm);
for(int i=0;i<len*2;i++)
b[i]=1ll*(1ll*b[i]*b[i]+t[i])%mod*c[i]%mod*inv2%mod;
dft(b,-1,lm);
memset(b+len,0,sizeof(int)*len);
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
{
int x=read();
a[x]++;
}
for(int i=1;i<=m;i++)
a[i]=(-a[i]*4+mod)%mod;
for(bt=1;(1<<bt)<=m;bt++);
lm=(1<<bt);
for(int i=0;i<lm;i++)
if(a[i])
a[i]=mod-4;
a[0]++;
kaigen(lm);
// for(int i=0;i<n;i++)
// cerr<<a[i]<<" "<<b[i]<<" "<<c[i]<<endl;
b[0]=(b[0]+1)%mod;
memset(c,0,sizeof(c));
qiuni(lm);
for(int i=1;i<=m;i++)
printf("%d\n",c[i]*2%mod);
return 0;
}

bzoj 3625: [Codeforces Round #250]小朋友和二叉树【NTT+多项式开根求逆】的更多相关文章

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

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

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

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

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

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

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

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

  5. [BZOJ3625][CF438E]小朋友和二叉树 (多项式开根,求逆)

    题面 题解 设多项式的第a项为权值和为a的二叉树个数,多项式的第a项表示是否为真,即 则,所以F是三个多项式的卷积,其中包括自己: ,1是F的常数项,即. 我们发现这是一个一元二次方程,可以求出,因为 ...

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

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

  7. [Codeforces Round #250]小朋友和二叉树

    题目描述: bzoj luogu 题解: 生成函数ntt. 显然这种二叉树应该暴力薅掉树根然后分裂成两棵子树. 所以$f(x)= \sum_{i \in c} \sum _{j=0}^{x-c} f( ...

  8. [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆)

    [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆) 题面 一棵二叉树的所有点的点权都是给定的集合中的一个数. 让你求出1到m中所有权 ...

  9. Codeforces Round #250 (Div. 1)E. The Child and Binary Tree

    题意:有一个集合,求有多少形态不同的二叉树满足每个点的权值都属于这个集合并且总点权等于i 题解:先用生成函数搞出来\(f(x)=f(x)^2*c(x)+1\) 然后转化一下变成\(f(x)=\frac ...

随机推荐

  1. BeagleBone Black Industrial 杂谈

    前言 原创文章,转载引用务必注明链接.水平有限一己拙见,欢迎指正. 本文使用markdown写成,为获得更好的阅读体验,推荐访问我的博客原文: ​ 初版BeagleBone Black(Rev A4) ...

  2. HTML页面底部无用留白

    HTML页面底部无用留白,可以再footer样式中加入: overflow: hidden; 如有错误,请您指正~

  3. 心情日记app总结 数据存储+服务+广播+listview+布局+fragment+intent+imagebutton+tabactivity+美工

    ---恢复内容开始--- 结果截图如下: 第一张图是程序主界面,主要是显示记事列表的一些个事件.旁边的侧拉框是自己登陆用的.可以设置密码.可以查看反馈与关于等信息. 点击第一张图片下方的图标,会显示不 ...

  4. PostgreSQL源码解读 基础结构 node

    一.node节点的定义 源代码路径postgresql-9.2.3/src/include/nodes/nodes.h 在查询解析SQL的查询部分,要用到大量的结构体,许多函数处理的逻辑类似,就是传入 ...

  5. 作为iOS程序员,最核心的60%能力有哪些?

    作为iOS程序员,最核心的60%能力有哪些?   一个合格的iOS程序员需要掌握多少核心技能?你和专业的开发工程师的差距有多大?你现在的水平能开发一个功能完整性能高效的iOS APP吗?一起来看看下面 ...

  6. mysql insert操作

    insert的语法 INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [(col_name,...)] ...

  7. cocos2d-x(vs2012)环境搭建(第一篇)[版本号:cocos2d-x-3.1.1]

    1.下载资源 下载cocos2d-x包V3.1.1,下载戳这里: http://www.cocos2d-x.org/download vs2012下载戳这里: http://www.xiazaiba. ...

  8. (Android 即时通讯) [悬赏],不管是谁发现一个漏洞奖励人民币1000元!

    悬赏,不管是谁发现一个漏洞奖励人民币1000元! 3Q Android 手机版即时通讯系统正式推出,可与电脑版 地灵(http://im.yunxunmi.com) 即时通讯系统互通!  适用于:小米 ...

  9. fminunc

    options = optimset('GradObj', 'on', 'MaxIter', 400); % Run fminunc to obtain the optimal theta% This ...

  10. CodeChef:Little Elephant and Colored Coins

    类似墨墨的等式 设f[2][j][k]表示a[i].c是否和当前颜色相同,到当前枚举到的颜色为止,颜色数为j,对mnv取模为k的最小数 这是个无限循环背包,用spfa优化 #include<cs ...