小清新题。
设 $x$ 到根的距离为 $d_x$,期望次数为 $f_x$ 。从 $x$ 到根的链中所有点都已染色时,此时的期望次数为 $\frac{1}{d_x}$,其余情况,只要这条链上有未染色的点,就可以对 $x$ 进行操作,并且每次都是从剩下可行点相等概率选择一个,这种情况下与将从 $x$ 到根的链中所有点全部染色的的期望相同,而这恰好可以理解为 $f_x$ 另一个定义。所有得到:$\displaystyle f_x=f_{fa}+\frac{1}{d_x}=\sum_{i=1}^{d_x}\frac{1}{i}$。
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
   | #include<iostream> #include<cstdio> using namespace  std; const int N=2e5+10,mod=998244353; template<class T> inline void read(T &x) {     x=0;int f=0;     char ch=getchar();     while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}     while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();     if(f)x=~x+1; } template<class T,class ...T1> inline void read(T &x,T1 &...x1) {     read(x),read(x1...); } int n; int d[N],sum[N]; inline int adj(int x){return (x>=mod)?x-mod:x;} inline int qpow(int x,int k=mod-2) {     int res=1;     while(k)     {         if(k&1)res=1ll*res*x%mod;         x=1ll*x*x%mod;         k>>=1;     }     return res; }
  int main() {     read(n);     d[1]=1;     for(int i=1;i<=n;i++)sum[i]=adj(sum[i-1]+qpow(i));     int ans=1;     for(int i=2,fa;i<=n;i++)     {         read(fa);         d[i]=d[fa]+1;         ans=adj(ans+sum[d[i]]);     }     printf("%d",ans);     return 0; }
   |