感觉关于树/图计数是一门博大精深的学问,不知道这辈子有没有搞到足够明白的机会了啊QwQ

一、无标号有根树计数:
基本上是这篇的详细版本。

考虑令fnf_nfn​表示n个点的无标号有根树数量,其生成函数为F(x)=∑i>0fixiF(x)=\sum_{i>0}f_ix^iF(x)=∑i>0​fi​xi;考虑如何计数fn+1f_{n+1}fn+1​,可以这么认为:等价于找n个点的森林,每颗树都是一个子问题;然后新增一个点当这些树的根。

一个直接的想法是:是不是可以枚举树的个数,然后的到:F(x)=x∑i>0Fi(x)F(x)=x\sum_{i>0}F^i(x)F(x)=x∑i>0​Fi(x)?然而这显然是错的,因为这样得到的答案中有重复计数,即如果我有两个完全相同的儿子,那么其二者的顺序应当是不计的;

因此考虑大小为k的树的选择情况,然后可能又会认为大小为k的树对fn+1f_{n+1}fn+1​那一项的贡献是:∑j≥0ifkxki\sum_{j\geq0}i^{f_{k}}x^{ki}∑j≥0​ifk​xki,但这还是错的,理由同上。

正确的姿势是,贡献应当是:(∑i≥0zik)fk\left(\sum_{i\geq0}z^{ik}\right)^{f_k}(∑i≥0​zik)fk​,也就是fkf_kfk​个相同的等比数列的乘积。一一对应的关系:假设第jjj个等比数列选择的那一项是ijki_jkij​k,那么最终对应的一种方案是,假如我们给这fkf_kfk​个大小为k的无标号有根树编号为1到fkf_kfk​,那么在考虑对fn+1f_{n+1}fn+1​的贡献中,第jjj种选了iji_jij​个。

最后我们把所有k的情况乘起来(下面即使k≥n+1k\geq n+1k≥n+1也不要紧):
[xn+1]F(x)=[xn+1]x∏k>0(∑i≥0xik)fk=[xn+1]∏k>0(11−xk)fk=[xn+1]∏k>0(1−xk)−fk[x^{n+1}]F(x)=[x^{n+1}]x\prod_{k>0}\left(\sum_{i\geq0}x^{ik}\right)^{f_k}\\=[x_{n+1}]\prod_{k>0}\left(\frac{1}{1-x^k}\right)^{f_k}=[x_{n+1}]\prod_{k>0}\left(1-x^k\right)^{-f_k}[xn+1]F(x)=[xn+1]xk>0∏​(i≥0∑​xik)fk​=[xn+1​]k>0∏​(1−xk1​)fk​=[xn+1​]k>0∏​(1−xk)−fk​
把那个[xn+1][x_{n+1}][xn+1​]去掉:
F(x)=x∏k>0(1−xk)−fkF(x)=x\prod_{k>0}\left(1-x^k\right)^{-f_k}F(x)=xk>0∏​(1−xk)−fk​
显然两边取对数:
ln⁡F(x)=ln⁡(x∏k>0(1−xk)−fk)=ln⁡x+∑k>0ln⁡((1−xk)−fk)=ln⁡x−∑k>0fkln⁡(1−xk)\ln F(x)=\ln\left(x\prod_{k>0}\left(1-x^k\right)^{-f_k}\right)\\=\ln x+\sum_{k>0}\ln \left(\left(1-x^k\right)^{-f_k}\right)\\=\ln x-\sum_{k>0}f_k\ln\left(1-x^k\right)lnF(x)=ln(xk>0∏​(1−xk)−fk​)=lnx+k>0∑​ln((1−xk)−fk​)=lnx−k>0∑​fk​ln(1−xk)
然后两边同时求导:
F′(x)F(x)=1x+∑k>0fkkxk−11−xk\frac{F'(x)}{F(x)}=\frac 1x+\sum_{k>0}f_k\frac{kx^{k-1}}{1-x^k}F(x)F′(x)​=x1​+k>0∑​fk​1−xkkxk−1​
化简这个式子,可以得到:
xF′(x)=F(x)+F(x)∑k>0fkkxk1−xkxF'(x)=F(x)+F(x)\sum_{k>0}f_kk\frac{x^k}{1-x^k}xF′(x)=F(x)+F(x)k>0∑​fk​k1−xkxk​
比较其第n项系数,可知(后面最后一项视为F(x)F(x)F(x)和若干多项式的乘积的和):
nfn=fn+∑i>0fi∑k>0fkk([xn−i]xk1−xk)nf_n=f_n+\sum_{i>0}f_i\sum_{k>0}f_kk\left([x^{n-i}]\frac{x^k}{1-x^k}\right)nfn​=fn​+i>0∑​fi​k>0∑​fk​k([xn−i]1−xkxk​)
我们知道:xk1−xk=∑i=1n−1xik=∑i>0[k∣i]xi\frac{x^k}{1-x^k}=\sum_{i=1}^{n-1}x^{ik}=\sum_{i>0}[k|i]x^i1−xkxk​=∑i=1n−1​xik=∑i>0​[k∣i]xi
因此:
nfn=fn+∑i=1n−1fi∑k>0fkk[k∣n−i]=fn+∑i=1n−1fi∑k∣n−ifkknf_n=f_n+\sum_{i=1}^{n-1}f_i\sum_{k>0}f_kk[k|n-i]=f_n+\sum_{i=1}^{n-1}f_i\sum_{k|n-i}f_kknfn​=fn​+i=1∑n−1​fi​k>0∑​fk​k[k∣n−i]=fn​+i=1∑n−1​fi​k∣n−i∑​fk​k
最后
fn=∑i=1n−1fi∑k∣n−ifkkn−1f_n=\frac{\sum_{i=1}^{n-1}f_i\sum_{k|n-i}f_kk}{n-1}fn​=n−1∑i=1n−1​fi​∑k∣n−i​fk​k​
后面那一项显然可以边算边处理,这样直接算是O(n2)O\left(n^2\right)O(n2)的,可以分治NTT做到O(nlg⁡2n)O\left(n\lg^2n\right)O(nlg2n)。

二、无标号无根树计数
其实做完上面的部分这一部分也就基本完成了:令hnh_nhn​表示n个点的无标号无根树,我们用有根树的情况减去当根不为重心的情况:
1)当n为奇数,此时重心只有一个,如果根不是重心,那么其一定有恰好一颗子树,其大小超过⌊n2⌋\left\lfloor\frac{n}{2}\right\rfloor⌊2n​⌋,枚举这个子树的大小并且扣去:
hn=fn−∑k=⌊n2⌋+1n−1fkfn−kh_n=f_n-\sum_{k=\left\lfloor\frac{n}{2}\right\rfloor+1}^{n-1}f_kf_{n-k}hn​=fn​−k=⌊2n​⌋+1∑n−1​fk​fn−k​
2)和奇数稍有不同的是,此时有可能有两个重心(只是有可能)。如果根不是重心,还是像奇数一样减去那颗大小最大的,然后如果重心是在边e的两端,那么要从总数减去断开e后两颗树不一样(此时在fnf_nfn​中会被计数两次)的情况:
hn=fn−(∑k=n2+1n−1fkfn−k)−(fn22)h_n=f_n-\left(\sum_{k=\frac{n}{2}+1}^{n-1}f_kf_{n-k}\right)-\binom{f_{\frac n2}}2hn​=fn​−⎝⎛​k=2n​+1∑n−1​fk​fn−k​⎠⎞​−(2f2n​​​)
这样可以在O(n)O(n)O(n)的求出某一项,也可以做一个卷积……

写了个O(n2)O\left(n^2\right)O(n2),去OEISOEISOEIS了一波确实没挂。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define lint long long
#define p 998244353
#define inv2 499122177
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define N 5010
using namespace std;
int f[N],g[N],h[N];
inline int fast_pow(int x,int k,int ans=1)
{   for(;k;k>>=1,x=(lint)x*x%p) if(k&1) ans=(lint)ans*x%p;return ans;  }
int main()
{int n;scanf("%d",&n),f[1]=h[1]=1;rep(i,1,n) g[i]=1;rep(i,2,n){rep(j,1,i-1) f[i]+=(lint)f[j]*g[i-j]%p,(f[i]>=p?f[i]-=p:0);f[i]=(lint)f[i]*fast_pow(i-1,p-2)%p;int t=(lint)i*f[i]%p;for(int j=i;j<=n;j+=i) g[j]+=t,(g[j]>=p?g[j]-=p:0);}rep(i,2,n){rep(j,i/2+1,i-1) h[i]+=(lint)f[j]*f[i-j]%p,(h[i]>=p?h[i]-=p:0);if(i%2==0) h[i]+=f[i/2]*(f[i/2]-1ll)%p*inv2%p,(h[i]>=p?h[i]-=p:0);h[i]=f[i]-h[i]+p,(h[i]>=p?h[i]-=p:0);}rep(i,1,n) printf("%d ",f[i]);printf("\n");rep(i,1,n) printf("%d ",h[i]);return !printf("\n");
}

「学习笔记」无标号生成树计数总结相关推荐

  1. 生成函数Euler变换学习笔记(无标号有根树计数)

    众所周知,对于有标号计数的指数型生成函数 f(x)f(x)f(x),将其任意地进行无顺序的组合,得到的生成函数是exp(f(x))exp(f(x))exp(f(x)). 而对于无标号计数的这样的组合, ...

  2. 「学习笔记」多项式的蛇皮操作

    文章目录 「学习笔记」多项式的蛇皮操作 前置知识 趋近 自然常数 对数 逆元 导函数 牛顿迭代与泰勒公式 不定积分与定积分 多项式乘法 多项式求逆元 多项式除法/取模 多项式牛顿迭代法 多项式开根 「 ...

  3. 「学习笔记」黑马面面布局开发

    「学习笔记」黑马面面布局开发 黑马面面布局开发 一.目的 1.1 技术方案 1.2 代码规范 1.2 目录规范 二.流程开发 2.1 蓝湖/摹客协作平台 2.2 适配方案 2.3 初始化文件 2.4 ...

  4. 「学习笔记」移动Web开发之flex布局9

    「学习笔记」移动Web开发之flex布局9 一.flex布局体验 1.1 传统布局与flex布局 1.2 初体验 二.flex布局原理 2.1 布局原理 三.flex布局父项常见属性 3.1 常见父项 ...

  5. 「学习笔记」品优购项目-上(页面公共部分 )

    「学习笔记」品优购项目-上 品优购项目-上 目标 品优购项目规划 网站制作流程 品优购项目介绍 品优购项目的学习目的 开发工具以及技术栈 开发工具 技术栈 品优购项目搭建工作 创建的文件夹如下(称为项 ...

  6. 「学习笔记」移动Web开发之rem适配布局10

    「学习笔记」移动Web开发之rem适配布局10 一.rem单位 1.1 rem 单位 二.媒体查询 2.1 什么是媒体查询 2.2 语法规范 2.2.1 mediatype 查询类型 2.2.2 关键 ...

  7. 「学习笔记」HTML5CSS3提高6(上)

    「学习笔记」HTML5&CSS3提高6(上) HTML5新特性 概述 语义化标签 (★★) 多媒体标签 视频标签- video(★★★) 基本使用 兼容写法 video 常用属性 音频标签- ...

  8. 「学习笔记」ISAP求最大流

    ISAP学习笔记 ISAP是OI中求最大流的常用方法之一.相对于Dinic,ISAP的速度提升了很多,但编码复杂度也上升了不少. 约定 采用邻接表存储图,对于每条弧,增加一条容量为0的逆向边. d数组 ...

  9. 「学习笔记」多项式相关

    序 学多项式也有好久了,可是我自己还没怎么认认真真推过柿子,导致啥都不会,然后被吊打. 看来再不回顾一下就不行了啊. 多项式乘法 写了一个好看一点的\(\mathrm{NTT}\)板子,仅供参考. i ...

最新文章

  1. github pages部署静态网页
  2. webmin远程命令执行漏洞(cve-2019-15107)深入分析
  3. python新手入门讲解-这是大多数新手入门之后强烈推荐的python自学入门指南秘笈...
  4. SGU155(笛卡尔树的构造)
  5. Python 第五天
  6. Android SQLite数据库demo。架构组件Room
  7. 【快速入门ORM框架之Dapper】大牛勿进系列
  8. 第E题 转换任意进制 (java方法直接解)==输入一个十进制数N,将它转换成R进制数输出
  9. 代码证年审 年报 附文档 短消息类服务接入代码 电信业务资源综合管理系统用户手册-码号年报 (码号使用单位)
  10. 美化博客园 添加网易云音乐及生成文章目录
  11. React高阶组件学习总结
  12. python | prophet的案例实践:趋势检验、突变点检验等
  13. python元组元素的提取_Python 元组
  14. 计算机毕业设计参考文献
  15. matlab离散系统的频率响应,离散系统的频率响应分析
  16. ubuntu linux目录绿色高亮问题
  17. 烽火戏诸侯 《剑来》 最新章节下载阅读,mobi、amz3、epub格式
  18. 商业智能助力 银行业数据“挖金”
  19. 制作linux包 u盘安装
  20. 分布式图数据库JanusGraph-简介

热门文章

  1. 测试计划包括哪些主要步骤和信息?
  2. SAR 101:合成孔径雷达简介
  3. Java项目:局域网内实现中控(远程开关机)
  4. NOIP2017初赛 格子连动问题
  5. 制冷量系数(CCF)在数据中心的价值
  6. 思维导图——带你快速掌握信号与传输介质
  7. elementui动态切换table列内容
  8. MySQL 示例数据库 employees 的导入与使用
  9. mps横式报表java实现
  10. 词典构造方法之LDA主题模型