图论计数
图论计数
\(prufer\) 序列
性质
长度为 \(n-2\)
每个点的出现次数即为在原树上的度数减一
与所有有标号无根树形成双射,所以一般用来计数有标号的树计数
基本公式
\(Cayley\) 公式
完全图的生成树个数为 \(n^{n-2}\) 个,即将 \(prufer\) 序列中每个位置任意放 \(1\sim n\)
广义 \(Cayley\) 公式
\(n\) 个点 \(k\) 个关键点,求无根树个数为 \(k\) 使得关键点两两不在同一棵树中的森林个数
数学归纳法证明即可,\(Ans=kn^{n-k-1}\)
图联通方案数
有 \(k\) 个连通块,每个连通块大小为 \(<s_1,s_2,s_3,\dots,s_k>\)
则用最少的边连通这些连通块的方案数为 \(n^{k-2}\prod_{i=1}^k s_i\)
\(Ans=\sum_{\sum deg_i=2k-2}\binom{k-2}{deg_1-1,deg_2-1,deg_3-1,\dots,deg_k-1}\prod_{i=1}^ks_i^{deg_i}\)
\(=\sum_{\sum deg_i=2k-2}\binom{k-2}{deg_1-1,deg_2-1,deg_3-1,\dots,deg_k-1}\prod_{i=1}^ks_i^{deg_i-1}\prod_{i=1}^ks_i\)
发现前面是多元二项式的展开 \((x_1+x_2+\dots+x_n)^k=\sum_{\sum c_i=k}\binom{k}{c_1,c_2,\dots,c_n}\prod_{i=1}^nx_i^{c_i}\)
则上式 \(=(s_1+s_2+\dots+s_k)^{k-2}\prod_{i=1}^ks_i=n^{k-2}\prod_{i=1}^k s_i\)
森林计数
有 \(n\) 个点,求形成 \(k\) 个无根森林的方案数
引入一个虚点并保证其度数为 \(k\) 即可,\(Ans=\binom{n-1}{k-1}n^{n-k}\)
有 \(n\) 个点,求形成 \(k\) 个有根森林的方案数
套用广义 \(Carley\) 即可,\(Ans=\binom{n}{k}kn^{n-k-1}\)
例题
- Problem 8280
- 要求有边 \((i,j)\) 就得有边 \((p_i,p_j)\),那么有边 \((p_i,p_j)\) 显然也得有边 \((p_{p_i},p_{p_j})\),观察形式,很容易想到将 \(i\) 向 \(p_i\) 连边,而如果有边 \((i,j)\) 则 \(i\) 的 \(k\) 级祖先 \(x\)、\(j\) 的 \(k\) 级祖先 \(y\),边 \((x,y)\) 也得有。对于一个排列建形如 \((i,p_i)\) 的边,相当于形成了若干个环,因为对于每个点入度出度均为 \(1\),所以考虑缩环
- 现在考虑如何连边,首先只可能二元环才可能在内部连边,其余多元环内部如果连边则一定会形成环,不符合树的定义,所以只能在环间连边,考虑如何在环间连边,设其中一个环大小为 \(n\) 另一个环大小为 \(m\),并将环看作序列,不妨设 \(n \le m\) 且这两个环的内部的一号点已经连上了,则这两个环的二号点也会相连,\(n\) 号点也会相连,而第一个环的 \(1\) 号点则又会连向第二个环的 \(n+1\) 号点,将式子列出,第一个环的一号点会连向的在第二个环中的编号为 \(xn\%m+1\) 将取模去掉 \(xn-ym+1\),发现是个二元一次方程,所以方程的解为 \(gcd(n,m)\) 的倍数,加上一之后就是 \(kgcd(n,m)+1\),对于第一个环中其他的点也是一样的,所连向的点之间的距离均为 \(gcd(n,m)\),所以不难想到将两个环按 \(gcd(n,m)\) 的长度进行划分,若两个环均能划分出 \(\ge2\) 个段,则取两个环的前两段,这四段一定会形成环,所以两个环能相连当且仅当大小成倍数关系,相连的方案数就是 \(min(n,m)\)
- 由于当大环相小环连接时,大环中的每个点都只会有一条出边,将大环看作儿子,小环看作父亲,正好符合树的定义,但是小环有没有可能成为儿子呢,如果一个小环连了个大环小环中的点可能会有多条出边连到大环中,而大环的这些点在后面连向其他小环时可能会连向小环中的同一个点,从而产生环(结合画图更好理解),所以得出结论,只能大环做儿子,小环做父亲
- 根据以上结论,从小到大枚举环的大小,挨个将环插入到树中,利用 \(prufer\) 序列即可,首先若当前枚举到大小为 \(i\) 的环,设大小为 \(i\) 的环有 \(a_i\) 个,则再枚举这 \(a_i\) 个环会形成多个棵树,这直接用森林计数公式即可,同时再乘上两边相连时产生的贡献,因为只是大小为 \(i\) 的环互相连成的森林,所以贡献都为 \(i\),再将这些森林接在先前 \(1\sim i\) 形成的树上即可
矩阵树定理
给定一个无向无权图,定义其的度数矩阵 \(D_{i,i}=deg_i\),与其的邻接矩阵 \(A_{i,j}=A_{j,i}=E(i,j)\),\(E(i,j)\) 表示 \(i\) 与 \(j\) 之间连的边的个数
则该图的 \(Laplace\) 矩阵(亦称 \(Kirchhoff\) 矩阵)\(L=D-A\),简记为“度减邻”,减法直接对应项相减即可
则该无向图的生成树个数为 \(t(G)=det(L(G))_{[n]\setminus {k},[n]\setminus {k}}\),说人话就是生成树个数等于 \(L(G)\) 矩阵去掉 \(k\) 行 \(k\) 列后的行列式的值,\(k\) 任意
例题
容斥&反演
\(DAG\) 计数
要对 \(DAG\) 进行计数那肯定得找子问题,对于 \(DAG\),有关联的东西就只有拓扑序了,所以不妨按找拓扑排序的思想来划分子问题
具体的,每次将 \(DAG\) 入度为 \(0\) 的点集取出来,剩下一些新的子图也都是 \(DAG\),成功的转化为子问题
例题
- Problem 5051
- 非常经典的一道 \(DAG\) 计数问题,可以先将结论记着:\(DAG\) 的容斥系数为 \((-1)^{|S|+1}\),\(S\) 表示入度为 \(0\) 的点集
- \(n\le 17\) 直接考虑状压 \(dp\),引用上面说到的 \(DAG\) 计数方法,设 \(f_S\) 表示点集 \(S\) 的生成 \(DAG\) 方案数,则一个显然的方程就是 \(f_S=\sum_{T\subseteq S,T\not =\emptyset}f_{S-T}2^{e(S,S-T)}\),其中 \(e(S,S-T)\) 表示点集 \(S,S-T\) 之间的跨越边数量,上面这个方程的意思就是枚举一个子集 \(T\) 表示点集 \(S\) 形成的 \(DAG\) 的入度为 \(0\) 的点集,将 \(T\) 取出剩下 \(S-T\) 继续递推,而后面一项则是每一条跨越边都可以选或者不选,若都不选了也没关系,剩下的 \(S-T\) 还是 \(DAG\)
- 但是这么做会有个问题,我们并不能保证点集 \(T\) 一定能取完点集 \(S\) 形成的 \(DAG\) 的所有入度为 \(0\) 的点,有可能会取少,导致算重,那算重了就容斥呗,这么小的数据范围正好适合容斥
- 容斥一共有两种方法,可以直接套用超集反演公式,然后化式子,也可以直接推反演系数,最后的结果都是一样的,因为套公式比较基础,这里说一下直接推反演系数的方法
- 要推反演系数,首先得考虑我们一共算重了多少次,设 \(RealT\) 表示真正入度为 \(0\) 的点集,\(T\) 表示我们钦定的入度为 \(0\) 的点集但实际上肯定真正入度为 \(0\) 的点集要多一点,这里的 \(T\) 跟上面的方程里的 \(T\) 意义相同,我们直接来看上面那个错误的方程,由于只要我们枚举的 \(T\) 为 \(RealT\) 的子集了,我们就一定会加入一次贡献,所以对于一个 \(DAG\) 我们一共会加入 \(\binom{|RealT|}{|T|}\) 次贡献,我们的目标就是对于每个 \(DAG\) 都只会算一次贡献,仿照子集反演的容斥系数,先给上面的方程带一个 \((-1)^{|T|}\) 的系数,如果上面的方程真的是子集容斥的形式,则每个 \(DAG\)应该会恰好被消完,即每个 \(DAG\) 会计算 \(0\) 次贡献,但是上面的方程需要保证 \(T\not= \emptyset\),所以还得把 \(T=\emptyset\) 的那一项给去掉,去掉之后每个 \(DAG\) 都会少 \(\binom{|RealT|}{0}\) 的贡献,即每个 \(DAG\) 都是 \(-1\) 的贡献,这时候我们给整体取个负即可,所以最终反演系数即为 \((-1)^{|T|+1}\),这里的 \(+1\) 就是取负,最终的方程就是 \(f_S=\sum_{T\subseteq S,T\not =\emptyset}f_{S-T}2^{e(S,S-T)}(-1)^{|T|+1}\)
- AT_dwacon6th_prelims_e Span Covering
- 把等号情况去掉就是巨神兵,加上等号后考虑将等号形成的连通块缩成一个方点,对方点做巨神兵,所以容斥系数就是 \((-1)^{cnt_T+1}\),\(cnt_T\) 表示 \(T\) 点集内部的连通块个数
- [P11714 清华集训 2014] 主旋律
-
\(DAG\) 容斥系数的应用,设 \(f_S\) 表示点集 \(S\) 内生成子图为恰好一个 \(SCC\) 的方案数,那么我们显然可以做一步简单容斥,变成总方案减去生成子图有至少两个 \(SCC\) 的方案数,而后者可以类比 \(DAG\) 计数,所以可以直接写出转移方程
-
\(f_S=2^{E(S,S)}-\sum_{S\subseteq T}(-1)^{cnt+1}g(T)2^{E(S-T,S-T)}2^{E(T,S-T)}\)
-
\(E(S,T)\) 表示有向边 \((u,v)\) 满足 \(u\in S,v\in T\) 的个数
-
\(2^{E(S,S)}\):总方案
-
\((-1)^{cnt+1}\):容斥系数,指数上为钦定的入读为 \(0\) 的点(在这道题中 \(DAG\) 上的一个点也表示一个 \(SCC\))的个数加一,即 \(SCC\) 的个数加一
-
\(g(T)\):没有入度的点的方案数,表示将点集 \(T\) 缩点后形成的所有 \(SCC\) 入度均为 \(0\) 的方案数
- 但是为了保证我们减去的方案是 \(SCC\) 有至少两个的方案,所以当 \(S=T\) 的时候,我们钦定 \(G(T)\) 的定义还要多加一条限制就是 \(SCC\) 至少有两个
-
\(2^{E(S-T,S-T)}\):剩下的点无限制,可随意连边
-
\(2^{E(T,S-T)}\):在没有入度的点和剩下的点之间连边,需要保证只能由没有入度的点连向剩下的点
-
-
由于 \(cnt\) 并不确定,而他又跟 \(g(S)\) 中的方案有紧密的联系,所以不妨让 \(g(S)\) 自己带上这个系数,即更换 \(g(S)\) 的定义为:缩点后形成奇数个 \(SCC\) 的方案数减去形成偶数个 \(SCC\) 的方案数
-
现在转移中就没有 \((-1)^{cnt+1}\) 了,可以直接转移
-
考虑 \(g(S)\) 的转移,由于 \(f\) 的转移会用到 \(g\),所以先将 \(g(S)\) 给转移了,枚举一个子集 \(T\) 然后转移即可,注意根据上述定义 \(T\) 不能为空或者等于 \(S\),且为乐避免算重,我们枚举的 \(T\) 要求必须包含 \(S\) 中的某个元素,如 \(T\) 必须包含 \(highbit(S)\)
-
然后转移 \(f(S)\),最后 \(g(S)\leftarrow g(S)+f(S)\) 将 \(SCC\) 只有一个的方案加入(之前不加入是为了 \(f\) 的转移)
-
至于 \(E(S,S),E(T,S-T)\) 直接对枚举到的每个 \(S\) 递推即可
-
符号化方法
无标号体系
无标号主要使用 \(OGF\) 来计数
集合的 \(Sequence\) 构造
考虑一个问题,构造一个 \(1\times i\) 长度的矩形的方案数是 \(f_i\),问用一些矩形拼成 \(1\times n\) 的矩形的方案数
考虑构造关于单个矩阵的方案数的 \(OGF\),\(F(x)=\sum_{i=0}^{\infty}f_ix^i\),则 \(SEQ(F)=\sum_{i=0}^{\infty}F^i(x)=\frac{1}{1-F(x)}\),\(SEQ(F)\) 就是答案的生成函数,其中当 \(i=0\) 的情况为 \(n=0\) 的方案数,所以必须得算进去
例如对于有根无标号且儿子之间有序的树计数,设 \(f_i\) 表示有 \(i\) 个节点的树的方案数,列出 \(f\) 的 \(OGF\) \(F(x)\),则固定第一层的树根,第二层的子树考虑递推,第二层的子树还是有根无标号树计数,生成函数同样是 \(F(x)\),而儿子之间是有序的所有构建 \(F(x)\) 的 \(SEQ\),所以 \(F(x)=xSEQ(F)=\frac{x}{1-F(x)}\),最前面的 \(x\) 表示树根,虽然加一个树根并不会影响方案数,但会将总结点个数加一,所以将 \(SEQ\) 平移一位,注意 \(F(x)\) 表示的是非空集合的方案数,所以最后不用加上空集的一
例题
- 括号序列
- 要对括号序列进行计数,那肯定先将括号序列建成树,由于最后建出来的为一颗森林,所以再加一个根节点把所有树连起来,相当于在原输入的括号序列的两边加上 \(()\)
- 在树上看看我们在操作什么,一操作即为删掉一个叶子,二操作即为合并一对相邻的兄弟,合并的意思即为将他俩的儿子集合合为一个,再将这两个点合为一个接在合并后的儿子集合上方,而且还只能合并一开始就是相邻兄弟关系的节点
- 假设我们知道了一层中哪些相邻兄弟会合并,那我们就把这些兄弟的儿子全部合并了,再把这些兄弟给合为一个节点,但是这么做会有个问题,我们删除 \()(\) 到底是在删哪个节点,我们只是处理了合并的操作,但删除也会包含方案数,所以假设我们要合 \(k\) 个点为一个点 \(u\),则我们在 \(u\) 的儿子中新增 \(k-1\) 个点,删除他们分别表示合并 \((1,2),(2,3),(3,4),\dots\),只有将 \(u\) 子树给删完后才能删 \(u\)
- 在新树上做树上拓扑序计数,这里并不需要 \(EGF\) 来有序归并,考虑树上拓扑序计数的另一个式子 \(n!\sum_{u}\frac{1}{size_u}\),这样我们只需要记录树中每个节点的 \(\frac{1}{size}\) 之积最后乘上一个阶乘即可,节点之间无关联所以直接用 \(OGF\) 即可
- 设 \(F(x)=\sum_{i=0}^{\infty}f_ix^i\) 表示答案的生成函数,\(G(x)=\sum_{i=0}^{\infty}g_ix^i\) 表示 \(i\) 个点,原来是一些连续的兄弟,把他们合并起来的方案数
- 由于 \(f,g\) 的递推中会乘上根节点的方案 \(\frac{1}{i}\),这在 \(OGF\) 中并不好表示,所以再设 \(H(x)=\sum_{i=0}^{\infty}if_ix^i\),\(xG'=x\sum_{i=0}^{\infty}ig_ix^{i-1}=\sum_{i=0}^{\infty}ig_ix^{i}\),表示不算根节点贡献的方案数
- 考虑列出转移式,由于新设的 \(OGF\) 给每个 \(i\) 次项乘上了 \(i\),所以递推的时候会与根贡献的 \(\frac{1}{i}\) 抵消掉,就不用考虑根的贡献了,所以 \(H=xSEQ(G)=\frac{x}{1-G}\),注意虽然我们将一些兄弟的儿子直接合并起来,但是方案数并不能直接用新合并出来的儿子集合的 \(f\) 来算,这样可能会把兄弟间新合并出来的 \()(\) 给删掉,所以必须按照原来的儿子集合的 \(f\) 来算,所以\(xG'=SEQ(H)-1=\frac{1}{1-H}-1\), \(SEQ(H)\) 表示只算兄弟的儿子的贡献,且兄弟之间儿子的贡献不能互相影响,最后的减一是因为注意到 \(SEQ\) 构造包含空集,但我们设的 \(xG'\) 并不包含空集,或者说 \(xG'\) 的 \(0\) 次项显然为 \(0\),而 \(SEQ(H)\) 的 \(0\) 次项显然为 \(1\)
- 最后将这两个式子联立一下,得出 \(GG'=G'-xG'-1\),对于这种自递推的形式都可以用分治 \(FFT\) 解决,具体的,两边同时取第 \(n\) 项,\([x^n]GG'=[x^n]G'-[x^n]xG'\),化简后得到 \(ng_n=(n-1)g_{n-1}+\sum_{i=0}^{n}g_ig_{n-i}(n-i)\),但是上面的自递推式还有个 \(+1\) 的常数,所以边界需要单独处理,直接 \(g_0=0,g_1=1\) 即可,直接分治 \(FFT\) 求解
集合的 \(Multiset\) 构造
又称 \(Euler\) 变换,对应有标号体系中的有标号 \(Set\) 构造
与有标号 \(Set\) 构造不同的是,对于两个排列顺序和结构相同的组合,在有标号体系中因为标号的缘故使得这两者互相区分,但在无标号体系中,这两者其实本质相同,所以相对来说无标号体系中的 \(Multiset\) 构造会更加复杂一些(从式子上就已经复杂许多了)
正如上文所说,\(Multiset\) 构造的最大问题就是两个本质相同的组合互不区分,所以方案显然只跟每种本质不同的组合的个数相关,所以不妨对每种本质不同的组合构造对应的 \(SEQ\),然后组合起来,对于一个大小为 \(i\) 的组合,他的 \(SEQ\) 构造为 \(\frac{1}{1-x^i}\),那么可以由此得出 \(Multiset\) 构造
\(MSET(F)=\prod_{i=1}^{\infty}\frac{1}{(1-x^i)^{f_i}}\),先枚举组合大小,然后每种大小有 \(f_i\) 种本质不同的组合,所以要乘 \(f_i\) 次
然后就可以来化式子了
\(G=MSET(F)=\prod_{i=1}^{\infty}\frac{1}{(1-x^i)^{f_i}}\)
\(\Leftrightarrow \ln G=\sum_{i=1}^{\infty}\ln\frac{1}{(1-x^i)^{f_i}}\)(有连乘,先取个对数化为求和)
\(\Leftrightarrow \ln G=-\sum_{i=1}^{\infty}f_i\ln(1-x^i)\)
\(\Leftrightarrow \frac{G'}{G}=-\sum_{i=1}^{\infty}f_i\frac{-ix^{i-1}}{1-x^i}\)(经典遇事不决就求导,注意链式法则)
\(\Leftrightarrow \frac{G'}{G}=\sum_{i=1}^{\infty}if_ix^{i-1}\frac{1}{1-x^i}\)
\(\Leftrightarrow \frac{G'}{G}=\sum_{i=1}^{\infty}if_ix^{i-1}\sum_{j=0}^{\infty}x^{ij}\)(将最后一项的完全背包展开)
\(\Leftrightarrow \frac{G'}{G}=\sum_{i=1}^{\infty}if_i\sum_{j=0}^{\infty}x^{i(j+1)-1}\)
\(\Leftrightarrow \frac{G'}{G}=\sum_{i=1}^{\infty}if_i\sum_{j=1}^{\infty}x^{ij-1}\)
\(\Leftrightarrow \ln G=\sum_{i=1}^{\infty}if_i\sum_{j=1}^{\infty}\frac{x^{ij}}{ij}\)(再积分回来)
\(\Leftrightarrow \ln G=\sum_{i=1}^{\infty}f_i\sum_{j=1}^{\infty}\frac{x^{ij}}{j}\)
\(\Leftrightarrow \ln G=\sum_{j=1}^{\infty}\frac{1}{j}\sum_{i=1}^{\infty}f_ix^{ij}\)(交换求和符号)
\(\Leftrightarrow \ln G=\sum_{j=1}^{\infty}\frac{F(x^j)}{j}\)
\(\Leftrightarrow MSET(F)=G=\exp\sum_{i=1}^{\infty}\frac{F(x^i)}{i}\)(再 \(exp\) 回去)
这样就得到了欧拉变换的最终式子
例题
-
-
先考虑有根树,由于是无标号体系,所以是 \(OGF\),设 \(F\) 为答案的生成函数,考虑找子问题递推处理,将树根去掉后会出现一些更小的有根树,这些有根树之间无序,所以是 \(MSET\) 构造,则有 \(F=xMSET(F)\),然后就可以开始化式子了
-
\(F=x\exp\sum_{i=1}^{\infty}\frac{F(x^i)}{i}\)
-
\(\Leftrightarrow F'=\exp\sum_{i=1}^{\infty}\frac{F(x^i)}{i}+x(\exp\sum_{i=1}^{\infty}\frac{F(x^i)}{i})'\)(开导!,注意乘法的求导)
-
\(\Leftrightarrow F'=\exp\sum_{i=1}^{\infty}\frac{F(x^i)}{i}+x\exp(\sum_{i=1}^{\infty}\frac{F(x^i)}{i})(\sum_{i=1}^{\infty}\frac{F(x^i)}{i})'\)(链式法则)
-
\(\Leftrightarrow F'=\exp\sum_{i=1}^{\infty}\frac{F(x^i)}{i}+x\exp(\sum_{i=1}^{\infty}\frac{F(x^i)}{i})\sum_{i=1}^{\infty}\frac{ix^{i-1}F'(x^i)}{i}\)(还有链式法则)
-
\(\Leftrightarrow F'=\exp\sum_{i=1}^{\infty}\frac{F(x^i)}{i}+F\sum_{i=1}^{\infty}x^{i-1}F'(x^i)\)(代入原式 \(F=x\exp\sum_{i=1}^{\infty}\frac{F(x^i)}{i}\))
-
\(\Leftrightarrow xF'=F+F\sum_{i=1}^{\infty}x^{i}F'(x^i)\)(两边同乘 \(x\) 后还可以再代一个原式)
-
令 \(G=\sum_{i=1}^{\infty}x^{i}F'(x^i)\)
-
\(\Leftrightarrow xF'=F+FG\)
-
到这里就可以使用高贵的牛顿迭代过去了,复杂度 \(O(n\log n)\),但常数巨大,可能不如分治 \(FFT\),所以如果要用分治 \(FFT\) 我们就还得继续往下推出递推式
-
\(\Leftrightarrow [x^n](xF')=[x^n](F+FG)\)
-
\(\Leftrightarrow nf_n=f_n+\sum_{i=0}^nf_ig_{n-i}\)
-
\(\Leftrightarrow f_n=\frac{1}{n-1}\sum_{i=1}^{n-1}f_ig_{n-i}\)(注意到 \(F\) 和 \(G\) 均没有常数项)
-
现在考虑 \(G\)
-
\(G=\sum_{i=1}^{\infty}x^{i}F'(x^i)\)
-
\(\Leftrightarrow [x^n]G=[x^n]\sum_{i=1}^{\infty}x^{i}F'(x^i)\)
-
\(\Leftrightarrow g_n=\sum_{i=1}^{n}[x^{n-i}]F'(x^i)\)
-
注意到 \(F'(x^i)\) 肯定只会在指数为 \(i\) 的倍数的时候系数才不为 \(0\),所以可以将上式缩小枚举范围
-
\(\Leftrightarrow g_n=\sum_{i|n}[x^{n-i}]F'(x^i)\)
-
\(\Leftrightarrow g_n=\sum_{i|n}[x^{n-i}]F'(x^i)\)
-
假设是 \(F\) 中的 \([x^k]\) 项对 \(g_n\) 产生了贡献,则这项在 \(F'(x^i)\) 中为 \(kf_kx^{i(k-1)}\),能产生贡献的条件为 \(i(k-1)=n-i\) 即 \(k=\frac{n}{i}\),所以可以将上式化简
-
\(\Leftrightarrow g_n=\sum_{i|n}\frac{n}{i}f_{\frac{n}{i}}\)
-
\(\Leftrightarrow g_n=\sum_{i|n}if_{i}\)
-
至此,我们每算出来一个 \(f\) 就可以在调和级数的时间内将后面的 \(g\) 加上贡献,然后就可以分治 \(FFT\) 求解了
-
现在我们已经可以做出有根树计数了,考虑给无根树定个根,既然要定根不妨找一个性质比较好的根,比如重心
-
所以我们只需要跑一遍有根树计数然后减去根不为重心的情况即可,根不为重心则一定有一个子树大小大于 \(\frac{n}{2}\),枚举这个子树大小合并上剩下的点即可
- 方案数为:\(\sum_{i=\left \lfloor \frac{n}{2} \right \rfloor +1}^nf_if_{n-i}\),是个卷积形式,直接 \(NTT\)
-
还有一种情况就是有两个重心,此时会算重,每一种有两个重心的树都会算两次,所以我们只需要减去拥有两个重心的树的个数即可,有两个重心的树其真正的重心其实是在那两个重心之间那条边上,而边两端的两个子树大小一定各为 \(\frac{n}{2}\),所以个数就是 \(\binom{f_{\frac{n}{2}}}{2}\),这里要注意两边的子树若长得一样则不会算重,因为若这两个子树同构则以任意一个重心为根时整棵树也都同构所以不会重也就不用减掉
-

浙公网安备 33010602011771号