TonyYin's Blog

Back

题意#

现在有 nn 次操作,每次从当前二叉树上的所有空位(节点的左/右儿子)中等概率选择一个,插入新点。

对最终 nn 个点的二叉树,求:两两节点距离之和的期望

题解#

加入第 ii 个点时,方案数为 ii,根据乘法原理,一共有 n!n! 种可能的二叉树。只需要计算这些树的权值和

由于是统计距离之和,考虑按边拆开计算,一条边被经过的次数,能直接算,是这条边两侧的节点个数的乘积。

所以先枚举边。形式化地,枚举 i[2,n]i\in[2, n],则当前边是 i,fatheri\langle i,\operatorname{father}_i\rangle,其被经过的次数为 sizei(nsizei)\operatorname{size}_{i}(n - \operatorname{size}_i).

由于 sizei\operatorname{size}_i 并不知道,所以再枚举子树大小 sizei[1,ni+1]\operatorname{size}_i\in[1, n-i+1].

接下来我们要确定树的形态,求满足 sizei\operatorname{size}_i 限制的方案数,按照插入的顺序分别考虑。

123i2i1iAi+1i+2n2n1nB\underbrace{1\quad2\quad3\quad \cdots\quad i-2\quad i-1\quad i}_{A}\quad\underbrace{ i+1\quad i+2\quad \cdots\quad n-2\quad n-1\quad n}_{B}

AA#

包含前 ii 个点,这些点和 ii 的子树没什么关系,都可以随便插入,共有 i!i! 种方案。

BB#

我们首先要从中选出 sizei1\operatorname{size}_i-1 个节点插入 ii 的子树,共有 (nisizei1)\dbinom{n-i}{\operatorname{size}_i-1} 种方案。

sizei\operatorname{size_i} 个点是可以以任意顺序组成二叉树的,共有 (sizei)!(\operatorname{size}_i)! 种方案。

对于 BB 中剩下的 nisizei+1n-i-\operatorname{size}_i+1 个点,它们都不可以放在 ii 的子树内,下面计算这部分的方案数。

上图中,i=9i=9,可以发现此时共有 8=i18=i-1 个位置可供选择。

并且,每当我们插入一个节点,可供选择的位置就会增加 11

所以把 BB 中剩下的点插入的方案数为:(i1)i(i+1)(nsizei1)=(nsizei1)!(i2)!(i-1)i(i+1)\cdots(n-\operatorname{size}_i-1)=\dfrac{(n-\operatorname{size}_i-1)!}{(i-2)!}.

把上面的方案数都乘起来,再乘上 i,fatheri\langle i,\operatorname{father}_i\rangle 这条边的贡献,得到答案的表达式:

Ans=i=2nsizei=1ni+1sizei(nsizei)i!(nisizei1)(sizei)!(nsizei1)!(i2)!\operatorname{Ans} = \sum_{i=2}^{n}\sum_{\operatorname{size}_i=1}^{n-i+1} \operatorname{size}_i(n - \operatorname{size}_i) \cdot i!\cdot \binom{n-i}{\operatorname{size}_i-1}(\operatorname{size}_i)! \cdot \frac{(n-\operatorname{size}_i-1)!}{(i-2)!}

i!i!(i2)!(i-2)! 合并,得到:

Ans=i=2nsizei=1ni+1sizei(nsizei)(nisizei1)(sizei)!(nsizei1)!i(i1)\operatorname{Ans} = \sum_{i=2}^{n}\sum_{\operatorname{size}_i=1}^{n-i+1} \operatorname{size}_i(n - \operatorname{size}_i) \cdot \binom{n-i}{\operatorname{size}_i-1}(\operatorname{size}_i)! \cdot {(n-\operatorname{size}_i-1)!}\cdot i(i-1)

预处理阶乘和组合数,O(n2)\mathcal{O}(n^2) 计算即可。

代码#

为了提高可读性,下面代码中统计答案部分的取模操作被省去,直接提交将获得 20pts\rm{20pts} 的好成绩。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 2e3 + 10;
int N, P;
int fac[MAXN], C[MAXN][MAXN], ans;
signed main() {
	cin >> N >> P;
	fac[0] = 1;
	for(int i = 1; i <= N; i++) fac[i] = fac[i - 1] * i % P;
	for(int i = 0; i <= N; i++) C[i][0] = 1;
	for(int i = 1; i <= N; i++) 
        for(int j = 1; j <= i; j++) 
        	C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % P;
	for(int i = 2; i <= N; i++) {
        for(int siz = 1; siz <= N - i + 1; siz++) {
			ans += C[N - i][siz - 1] * siz * (N - siz) * fac[siz] * fac[N - siz - 1] * i * (i - 1);
		}
	}
	cout << ans << endl;
	return 0;
}
cpp
【洛谷-P4492】[HAOI2018]苹果树
https://www.tonyyin.top/blog/oi-solution/p4492
Author TonyYin
Published at December 26, 2021
Comment seems to stuck. Try to refresh?✨