小清新题。
设 $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; }
|