A
给定一棵 n 个点的有根树,节点编号为 1~n,根节点为 1。你会不停地重复 以下操作,直到所有点被覆盖为止:等概率随机树上的一个未被覆盖的点,并 覆盖这个点到根路径上的所有点。请问你的期望操作次数是多少?为了避免高 精度运算,你只需要输出答案对 998244353 取模后的结果。
概率期望经典入门题,根据期望的线性性,答案就是每个点被选到的期望之和,每个点的贡献为一,所以只需要求每个点被选到的概率即可,每个点必须在它的子树中的点被选之前选,所以概率是
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MOD = 998244353;
const int N = 10000000;
int n, head[N + 50], num, inv[N + 50], siz[N + 50], f[N + 50];
void Read(int &x)
{
x = 0; int p = 0; char st = getchar();
while (st < '0' || st > '9') p = (st == '-'), st = getchar();
while (st >= '0' && st <= '9') x = (x << 1) + (x << 3) + st - '0', st = getchar();
x = p ? -x : x;
return;
}
struct Node
{
int next, to;
} edge[N * 2 + 50];
void Addedge(int u, int v)
{
edge[++num] = (Node){head[u], v};
head[u] = num;
return;
}
int main()
{
Read(n);
inv[1] = 1;
for (int i = 2; i <= n; i++) Read(f[i]), inv[i] = 1LL * (MOD - MOD / i) * inv[MOD % i] % MOD;
for (int i = n; i >= 1; i--) siz[i]++, siz[f[i]] += siz[i];
int ans = 0;
for (int i = 1; i <= n; i++) (ans += inv[siz[i]]) %= MOD;
printf("%d", ans);
re