发电机 - 期望

题目大意:给你一棵初始全白的树,每次随机选择一个白色的点并将其到根的路径染黑。问期望多少次全染黑。
题解:考虑期望的线性性,一个点对答案有1的贡献当且仅当其在其子树前被染黑,概率是1/sz(x)。累加即可。

#include<bits/stdc++.h>
#define gc getchar()
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define mod 998244353
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
namespace IO { const int S=(1<<20)+5;char buf[S],*H,*T;inline char getc() { if(H==T) T=(H=buf)+fread(buf,1,S,stdin);if(H==T) return -1;return *H++; }
    inline int inn() { int x=0,c=getc();while(!isdigit(c)) c=getc();while(isdigit(c)) x=(((x<<2)+x)<<1)+(c^'0'),c=getc();return x; } }using namespace IO;
inline int fast_pow(int x,int k,int ans=1) { for(;k;k>>=1,x=(lint)x*x%mod) (k&1)?ans=(lint)ans*x%mod:0;return ans; }
const int N=10000010;int f[N],fv[N],inv[N],sz[N],p[N];
inline int prelude(int n)
{
    rep(i,f[0]=1,n) f[i]=(lint)f[i-1]*i%mod;
    fv[n]=fast_pow(f[n],mod-2);
    for(int i=n-1;i>=0;i--) fv[i]=(i+1ll)*fv[i+1]%mod;
    rep(i,1,n) inv[i]=(lint)f[i-1]*fv[i]%mod;return 0;
}
int main()
{
    int n=inn(),ans=0;prelude(n);
    rep(i,2,n) p[i]=inn(),sz[i]=1;sz[1]=1;
    for(int i=n;i>1;i--) sz[p[i]]+=sz[i];
    rep(i,1,n) ans+=inv[sz[i]],(ans>=mod?ans-=mod:0);
    return !printf("%d\n",ans);
}

猜你喜欢

转载自blog.csdn.net/Mys_C_K/article/details/83747240