Description

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

Solution

设 \(f[i]\) 为点权为 \(i\) 的二叉树的方案, \(c[i]\) 表示 \(i\) 是否在集合 \(c\) 中。

所以 \(f[i]=\sum\limits_{j=1}^{i} c[j]\cdot\sum\limits_{p=0}^{i-j}f[p]\cdot \sum\limits_{k=0}^{i-j-p}f[k],f[0]=1\)

发现这是个卷积形式,也就是说 \(f[i+j+k]=c[i]\cdot f[j]\cdot f[k]\),即 \(f=c\times f\times f\)。

解一下方程,\(f=\frac{1\pm \sqrt{1-4c}}{2c}\)

然而 \(c\) 的常数项为 \(0\),所以不能求逆。尝试分子有理化解得 \(f=\frac2{1\pm\sqrt{1-4c}}\)

当 \(x=0\) 时,\(c=0,f=1\),所以分母只能取正号。

求逆+开根即可。

Code

#include<bits/stdc++.h>
using std::min;
using std::max;
using std::swap;
using std::vector;
typedef double db;
typedef long long ll;
#define pb(A) push_back(A)
#define pii std::pair<int,int>
#define all(A) A.begin(),A.end()
#define mp(A,B) std::make_pair(A,B)
const int N=4e5+5;
const int mod=998244353;
#define inv(x) ksm(x,mod-2)int lim,rev[N],f[N];
int n,m,tmpa[N],c[N];
int a[N],b[N],tmpb[N];int ksm(int a,int b,int ans=1){while(b){if(b&1) ans=1ll*ans*a%mod;a=1ll*a*a%mod;b>>=1;} return ans;
}void ntt(int *f,int opt){for(int i=0;i<lim;i++) if(i<rev[i]) swap(f[i],f[rev[i]]);for(int mid=1;mid<lim;mid<<=1){int tmp=ksm(3,(mod-1)/(mid<<1));if(opt<0) tmp=inv(tmp);for(int R=mid<<1,j=0;j<lim;j+=R){int w=1;for(int k=0;k<mid;k++,w=1ll*w*tmp%mod){int x=f[j+k],y=1ll*w*f[j+k+mid]%mod;f[j+k]=(x+y)%mod,f[j+k+mid]=(mod+x-y)%mod;}}} if(opt<0)for(int in=inv(lim),i=0;i<lim;i++) f[i]=1ll*f[i]*in%mod;
}void get(int n){lim=1;while(lim<=n) lim<<=1;for(int i=1;i<lim;i++) rev[i]=(rev[i>>1]>>1)|(i&1?lim>>1:0);
}void solveinv(int len,int *a,int *b){if(len==1) return b[0]=inv(a[0]),void();solveinv(len>>1,a,b);get(len);for(int i=0;i<len;i++) tmpa[i]=a[i];ntt(tmpa,1),ntt(b,1);for(int i=0;i<lim;i++) b[i]=1ll*b[i]*(2ll-1ll*tmpa[i]*b[i]%mod+mod)%mod;ntt(b,-1);for(int i=len;i<lim;i++) b[i]=0;for(int i=0;i<lim;i++) tmpa[i]=0;
}void solvesqr(int len,int *a,int *b){if(len==1) return b[0]=1,void();solvesqr(len>>1,a,b);solveinv(len,b,tmpb);get(len);for(int i=0;i<len;i++) tmpa[i]=a[i];ntt(tmpb,1),ntt(tmpa,1);for(int i=0;i<lim;i++) tmpa[i]=1ll*tmpa[i]*tmpb[i]%mod;ntt(tmpa,-1);for(int i=0,inv2=mod+1>>1;i<lim;i++) b[i]=1ll*(tmpa[i]+b[i])%mod*inv2%mod;for(int i=len;i<lim;i++) b[i]=0;for(int i=0;i<lim;i++) tmpa[i]=tmpb[i]=0;
}int getint(){int X=0,w=0;char ch=getchar();while(!isdigit(ch))w|=ch=='-',ch=getchar();while( isdigit(ch))X=X*10+ch-48,ch=getchar();if(w) return -X;return X;
}signed main(){n=getint(),m=getint();for(int i=1;i<=n;i++){int x=getint();a[x]=1;}for(int i=1;i<=m;i++) if(a[i]) a[i]=mod-4;get(m);a[0]=1;solvesqr(lim,a,b);get(m);b[0]++;solveinv(lim,b,c);for(int i=1;i<=m;i++) printf("%lld\n",2ll*c[i]%mod);return 0;
}

转载于:https://www.cnblogs.com/YoungNeal/p/10211170.html

[CF438E] 小朋友和二叉树相关推荐

  1. [bzoj3625][Codeforces Round #250]小朋友和二叉树 (生成函数)

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

  2. BZOJ #3625 CF #438E 小朋友和二叉树

    清真多项式题 BZOJ #3625 codeforces #438E 题意 每个点的权值可以在集合$ S$中任取 求点权和恰好为$[1..n]$的不同的二叉树数量 数据范围全是$ 10^5$ $ So ...

  3. [学习笔记]多项式开根

    还是倍增思想 每一层 还要套一个多项式求逆 所以O(nlog^2n),常数也不小 数组比较多 再trick一下 得到: $T=(T'+F*inv(T'))*inv2$ 可以只算一次多项式求逆,一次NT ...

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

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

  5. 【BZOJ3684】大朋友和多叉树(拉格朗日反演)

    题目链接 题意 求满足如下条件的多叉树个数: 1.每一个点的儿子个数在给定的集合 \(S\) 内 2.总的叶子节点树为 \(s\) 儿子之间有顺序关系,但节点是没有标号的. Sol 拉格朗日反演板子题 ...

  6. 有关多项式处理的各种算法总结

    有关多项式处理的各种算法总结 有关多项式处理的各种算法总结 前言 1.一些定义的简要介绍 2.牛顿迭代 3.多项式求逆 4.多项式求lnln\ln 5.多项式开方 6.多项式求指数函数(exp) 7. ...

  7. 几乎刷完了力扣所有的树题,我发现了这些东西

    点击蓝色"力扣加加"关注我哟 加个"星标",带你揭开算法的神秘面纱! ❝ 这是力扣加加第「28」篇原创文章 先上下本文的提纲,这个是我用 mindmap 画的一 ...

  8. GOOD BYE OI

    大米饼正式退役了,OI给我带来很多东西 我会的数学知识基本都在下面了 博客园的评论区问题如果我看到了应该是会尽力回答的... 这也是我作为一个OIer最后一次讲课的讲稿 20190731 多项式乘法 ...

  9. 小朋友学数据结构(3):二叉树的建立和遍历

    小朋友学数据结构(3):二叉树的建立和遍历 一.基本概念 BinaryTree.png 二叉树:每个结点的子结点个数不大于2的树,叫做二叉树. 根结点:最顶部的那个结点叫做根结点,根结点是所有子结点的 ...

  10. CF438E The Child and Binary Tree(有意思的生成函数 + 多项式求逆 + 多项式开方)

    整理的算法模板合集: ACM模板 点我看多项式全家桶(●^◡_◡◡​^●) CF438E The Child and Binary Tree 简单的黑题 首先我们发现模数为99824435399824 ...

最新文章

  1. kafka中controller的作用_Kafka 常见问题汇总
  2. AtCoder AGC037E Reversing and Concatenating
  3. (转)在Myeclipse中查看android源码就是这么easy
  4. 7805输入电流有要求吗_防雷!防护电路在PCB走线方面的要求(某500强企业内部资料~)...
  5. Win-MASM64汇编语言-CMP/CMPSB/CMPSW/CMPSD/JNE/JCXZ
  6. Hello China操作系统运行截图(完整版)
  7. 机器学习笔记(1)决策树
  8. c语言sigaction,C语言中的Sigaction和setitimer
  9. 2019最新python下载安装详解
  10. php依赖安装顺序,PHP安装GD依赖
  11. js 实现2的n次方计算函数_x的10的n次方解决js浮点数计算
  12. 微信小程序|基于小程序实现人脸识别对比
  13. 【爬虫1】爬虫和反爬虫介绍
  14. pycharm 文件名不同颜色所代表的含义
  15. js实现数组按拼音排序
  16. 【转】 Linkdrops:以太坊上发红包的开源标准
  17. 关于ElasticSearch (ES)
  18. 阿里面试必过的 Java 面试参考指南全集
  19. Typora的初步使用及Markdown语法总结
  20. 2021年Java面经分享:java基础入门清华大学出版社课后答案

热门文章

  1. linux下grub的设置密码,grub设置密码
  2. nacos动态配置数据源_Sentinel使用Nacos存储规则及同步
  3. element step控件点击事件
  4. 港顺计算机怎么放音乐,csgo怎么放歌 CSGO内置语音播放歌曲
  5. SQLserver插入\更新中文乱码
  6. 【渝粤教育】国家开放大学2019年春季 2106宪法学 参考试题
  7. [渝粤教育] 西南科技大学 会计学原理 在线考试复习资料(2)
  8. 计算机视觉实战(四)图像形态学操作
  9. 数组排序:冒泡法和选择法
  10. 这些Python骚操作,你知道吗?