题面

Description

我们的小朋友很喜欢计算机科学,而且尤其喜欢二叉树。

考虑一个含有\(n\)个互异正整数的序列\(c_1,c_2,\ldots,c_n\)。如果一棵带点权的有根二叉树满足其所有顶点的权值都在集合\({c_1,c_2,\ldots,c_n}\)中,我们的小朋友就会将其称作神犇的。并且他认为,一棵带点权的树的权值,是其所有顶点权值的总和。

给出一个整数\(m\),你能对于任意的\(s(1≤s≤m)\)计算出权值为\(s\)的神犇二叉树的个数吗?请参照样例以更好的理解什么样的两棵二叉树会被视为不同的。

我们只需要知道答案关于\(998244353\)(\(7×17×223+1\),一个质数)取模后的值。

Input

第一行有\(2\)个整数\(n,m(1≤n≤10^5,1≤m≤10^5)\)。

第二行有\(n\)个用空格隔开的互异的整数\(c_1,c_2,\ldots,c_n(1≤c_i≤10^5)\)。

Output

输出\(m\)行,每行有一个整数。第\(i\)行应当含有权值恰为\(i\)的神犇二叉树的总数。请输出答案关于\(998244353\)(\(=7×17×223+1\),一个质数)取模后的结果。

Sample Input #1

2 3

1 2

Sample Output #1

1

3

9

Sample Input #2

3 10

9 4 3

Sample Output #2

0

0

1

1

0

2

4

2

6

15

Sample Input #3

5 10

13 10 6 4 15

Sample Output #3

0

0

0

1

0

1

0

2

0

5

HINT

对于第一个样例,有9个权值恰好为3的神犇二叉树:

分析

设$$v_i=\sum_{k=0}^n[c_k=i]$$

也即\(k\)在\(c\)中的出现次数(在此处只能为\(1\)或\(0\))。

设\(V(x)\)为\(v\)的生成函数:$$V(x)=\sum_{k=0}^\infty v_k x^k$$

设权值为\(i\)的神犇二叉树的个数为\(f_i\),则我们枚举根的权值和左子树的大小,可以得到一个递归式:$$f_i=\sum_{k=0}^i v_k\sum_{j=0}^{i-k}f_j f_{i-k-j}=\sum_{x+y+z=i}v_x f_y f_z$$

当\(i=0\)时,$$f_0=1$$

那么我们发现这是一个三重卷积。我们知道数列的卷积相当于生成函数的乘法,那么我们设\(f\)的生成函数\(F(x)\)为:$$F(x)=\sum_{k=0}^\infty f_k x^k$$

则我们可以得到一个关于\(F(x)\)的一元二次方程(记得要加上\(f_0=1\)时的情况):$$F(x)=V(x)F(x)^2+1$$

也即:$$V(x)F(x)^2-F(x)+1=0$$

那么我们使用二次方程求根公式得到:$$F(x)=\frac{1\pm\sqrt{1-4V(x)}}{2 V(x)}$$

那么到底哪个才是真的\(F(x)\)呢?

  • 若\(F(x)=\displaystyle\frac{1+\sqrt{1-4V(x)}}{2V(x)}\):

若\(x\)趋向于零,则\(F(x)\)就会趋向于\(f_0\)的值。那么我们求\(F(x)\)在\(x\to0\)下的极限:$$\lim_{x\to0}\frac{1+\sqrt{1-4V(x)}}{2V(x)}$$

因为\(v_0=0\),所以当\(x\to0\)时\(V(x)\to0\)。则有上式相当于:$$\lim_{x\to0}\frac{1+\sqrt{1-4x}}{2x}$$

显然,由于当\(x\to0\)时有\(2x\to0\)且\(1+\sqrt{1-4x}\to2\),则有:$$\lim_{x\to0}\frac{1+\sqrt{1-4x}}{2x}=\infty$$

舍去。

  • 若\(F(x)=\displaystyle\frac{1-\sqrt{1-4V(x)}}{2V(x)}\):

同理,有:$$\lim_{x\to0}\frac{1-\sqrt{1-4V(x)}}{2V(x)}=\lim_{x\to0}\frac{1-\sqrt{1-4x}}{2x}$$

我们发现当\(x\to0\)时\(1-\sqrt{1-4x}\to0\)且\(2x\to0\),则我们应用洛必达法则。分子求导可得:$$\frac{d(1-\sqrt{1-4x})}{d x}=\frac{d(1-\sqrt{1-4x})}{d(1-4x)}\frac{d(1-4x)}{d x}=-\frac{1}{2\sqrt{1-4x}}\times(-4)=\frac{2}{\sqrt{1-4x}}$$

分母求导可得:$$\frac{d(2x)}{d x}=2$$

则有:$$\lim_{x\to0}\frac{1-\sqrt{1-4x}}{2x}=\frac{\lim\limits_{x\to0}\frac{2}{\sqrt{1-4x}}}{\lim\limits_{x\to0}2}=\frac{2}{2}=1$$

符合\(f_0=1\)。

综上,有$$F(x)=\frac{1-\sqrt{1-4V(x)}}{2V(x)}$$

为了方便计算,我们构造一个平方差,上下同乘\(1+\sqrt{1-4V(x)}\):$$F(x)=\frac{\left[1-\sqrt{1-4V(x)}\right]\left[1+\sqrt{1-4V(x)}\right]}{2V(x)\left[1+\sqrt{1-4V(x)}\right]}=\frac{2}{1+\sqrt{1-4V(x)}}$$

那么我们多项式求逆+多项式求倒解决这道题。

详见https://blog.csdn.net/ez_tjy/article/details/80213166

代码

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. using namespace std;
  5. typedef long long ll;
  6. const ll p=998244353,g=3;
  7. int nn,n,m,r[262145];
  8. ll inv[262146],c[262145],gn[2][262145],ans;
  9. inline ll pow(ll a,int b){
  10. ll ans=1;
  11. while(b){
  12. if(b&1)ans=ans*a%p;
  13. a=a*a%p;
  14. b>>=1;
  15. }
  16. return ans;
  17. }
  18. inline ll add(ll a,ll b){return a+b>p?a+b-p:a+b;}
  19. inline ll cut(ll a,ll b){return a-b<0?a-b+p:a-b;}
  20. void init(){
  21. for(n=1;n<=m;n<<=1);
  22. nn=n;
  23. gn[0][0]=gn[1][0]=1;
  24. gn[0][1]=pow(g,(p-1)/(n<<1));
  25. gn[1][1]=pow(gn[0][1],p-2);
  26. for(int i=2;i<(n<<1);i++){gn[0][i]=gn[0][i-1]*gn[0][1]%p;gn[1][i]=gn[1][i-1]*gn[1][1]%p;}
  27. inv[1]=1;
  28. for(int i=2;i<=(n<<1);i++)inv[i]=inv[p%i]*(p-p/i)%p;
  29. }
  30. void NTT(ll c[],int n,int tp=1){
  31. for(int i=0;i<n;i++){
  32. r[i]=(r[i>>1]>>1)|((i&1)*(n>>1));
  33. if(i<r[i])swap(c[i],c[r[i]]);
  34. }
  35. for(int i=1;i<n;i<<=1){
  36. for(int j=0;j<n;j+=(i<<1)){
  37. for(int k=0;k<i;k++){
  38. ll x=c[j+k],y=gn[tp!=1][nn/i*k]*c[j+k+i]%p;
  39. c[j+k]=add(x,y);
  40. c[j+k+i]=cut(x,y);
  41. }
  42. }
  43. }
  44. }
  45. void INTT(ll c[],int n){
  46. NTT(c,n,-1);
  47. for(int i=0;i<n;i++)c[i]=c[i]*inv[n]%p;
  48. }
  49. void inverse(ll c[],int n=n){
  50. static ll t[262145],tma[262145];
  51. t[0]=pow(c[0],p-2);
  52. for(int k=2;k<=n;k<<=1){
  53. for(int i=0;i<(k<<1);i++)tma[i]=(i<k?c[i]:0);
  54. for(int i=(k>>1);i<(k<<1);i++)t[i]=0;
  55. NTT(tma,k<<1);
  56. NTT(t,k<<1);
  57. for(int i=0;i<(k<<1);i++)t[i]=cut(add(t[i],t[i]),t[i]*t[i]%p*tma[i]%p);
  58. INTT(t,k<<1);
  59. }
  60. memcpy(c,t,sizeof(ll)*n);
  61. }
  62. void sqrt(ll c[],int n=n){
  63. static ll t[262145],tma[262145],tmb[262145];
  64. t[0]=1;
  65. for(int k=2;k<=n;k<<=1){
  66. for(int i=0;i<k;i++)tma[i]=add(t[i],t[i]);
  67. inverse(tma,k);
  68. for(int i=0;i<(k<<1);i++)tmb[i]=(i<k?c[i]:0);
  69. NTT(tma,k<<1);
  70. NTT(tmb,k<<1);
  71. for(int i=0;i<(k<<1);i++){
  72. ll tmp=tma[i];
  73. tma[i]=t[i];
  74. t[i]=tmp*tmb[i]%p;
  75. }
  76. INTT(t,k<<1);
  77. for(int i=0;i<(k<<1);i++)t[i]=(i<k?add(t[i],tma[i]*inv[2]%p):0);
  78. }
  79. memcpy(c,t,sizeof(ll)*n);
  80. }
  81. int main(){
  82. scanf("%d%d",&n,&m);
  83. for(int i=1;i<=n;i++){
  84. int x;
  85. scanf("%d",&x);
  86. c[x]=p-4;
  87. }
  88. c[0]=1;
  89. init();
  90. sqrt(c);
  91. c[0]=2;
  92. inverse(c);
  93. for(int i=1;i<=m;i++)printf("%lld\n",add(c[i],c[i]));
  94. }

[BZOJ3625][CF438E]小朋友和二叉树的更多相关文章

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

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

  2. BZOJ3625 CF438E 小朋友与二叉树

    心态崩了 不放传送门了 辣鸡bz 还是正经一点写一下题解= = 就是显然我们可以把权值写成生成函数形式g(0/1序列)来表示权值是否出现 然后f来表示总的方案数 可以列出 分别枚举左右子树和空树的情况 ...

  3. [CF438E] 小朋友和二叉树

    Description 给定一个整数集合 \(c\),对于每个 \(i\in[1,m]\),求有多少种不同的带点权的二叉树使得这棵树点权和为 \(i\) 并且顶点的点权全部在集合 \(c\) 中.\( ...

  4. 【bzoj3625】【xsy1729】小朋友和二叉树

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

  5. 【BZOJ3625/CF438E】小朋友和二叉树(多项式求逆,多项式开方)

    [BZOJ3625/CF438E]小朋友和二叉树(多项式求逆,多项式开方) 题面 BZOJ CodeForces 大致题意: 对于每个数出现的次数对应的多项式\(A(x)\) 求\[f(x)=\fra ...

  6. 【CF438E】小朋友和二叉树 解题报告

    [CF438E]小朋友和二叉树 Description ​ 我们的小朋友很喜欢计算机科学,而且尤其喜欢二叉树. ​ 考虑一个含有\(n\)个互异正整数的序列\(c_1,c_2,\dots,c_n\). ...

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

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

  8. 「BZOJ 3645」小朋友与二叉树

    「BZOJ 3645」小朋友与二叉树 解题思路 令 \(G(x)\) 为关于可选大小集合的生成函数,即 \[ G(x)=\sum[i\in c ] x^i \] 令 \(F(x)\) 第 \(n\) ...

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

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

随机推荐

  1. 阿里云部署安装redis无法访问

    ps:我在linux上安装redis后发现一直端口不通连接不上,折腾一晚上.后来在阿里云官方回复(机器人)中看到下面的回复:       2019/02/28 22:50 自己一试,过完是端口监听是本 ...

  2. Java调用webservice接口方法(SOAP message、xfire、axis)

    webservice的 发布一般都是使用WSDL(web service descriptive language)文件的样式来发布的,在WSDL文件里面,包含这个webservice暴露在外面可供使 ...

  3. cf314E. Sereja and Squares(dp)

    题意 题目链接 给你一个擦去了部分左括号和全部右括号的括号序列,括号有25种,用除x之外的小写字母a~z表示.求有多少种合法的括号序列.答案对4294967296取模.合法序列不能相交,如()[],( ...

  4. react的setState使用中遇到的问题

    setState()更新的数据和自己预期的不一致 对 React 新手来说,使用 setState 是一件很复杂的事情.即使是熟练的 React 开发,也很有可能因为 React 的一些机制而产生一些 ...

  5. js或者jq判断一段文字中是否有自己想要的那几个字,如果有就把那几个字变成红色

    如何判断一段文字中是否有自己想要的那几个字,如果有就把那几个字变成红色(在html中)比如有body中有这么一串文字“驾驶的后视镜的华盛顿”,想要判断里面是否有“驾驶”这两个字,如果有就把这两个字变成 ...

  6. Python开发环境Wing IDE设置Python路径详解

    在使用Wing IDE的时候,Python源代码取决于PYTHONPATH(无论是外部或通过内部改变sys.path系统设置),用户需要将路径设置到Wing IDE中. 这个值可以从项目菜单和工具栏的 ...

  7. 【extjs6学习笔记】1.16 初始: 关于主题

    打开app.json,里面有主题设置 主题说明 theme-base 这个包是所有其他主题的基础主题,是唯一没有父主题的主题. 它包含Ext JS组件和布局正常工作绝对必需的最低限度的一组CSS规则. ...

  8. Weblogic 10.3.6.0 集群搭建

    Weblogic 集群搭建 Oracle的Weblogic分开发者版本和生产版本,有32位和64位.一般生产版本的weblogic是64位的,安装文件是一个大小为1G多的jar包.去oracle官网上 ...

  9. jQuery_2_常规选择器-简单选择器

    JQuery最核心的组成部分就是:选择器引擎.它继承了css的语法,可以对DOM元素的标签名.属性名.状态等进行快速准确的选择. jQuery选择器的写法与CSS 选择器十分类似,只不过他们的功能不同 ...

  10. (转) HTTP Request header

    HTTP Request header 当今web程序的开发技术真是百家争鸣,ASP.NET, PHP, JSP,Perl, AJAX 等等. 无论Web技术在未来如何发展,理解Web程序之间通信的基 ...