【题解】[Codeforces 1067E] Random Forest Rank【结论题 概率DP】
题意
给定一棵树,每条边有 \(\dfrac{1}{2}\) 的概率出现,求该森林邻接矩阵的轶的期望。\(n\leq 5\times 10^5\)
题解
结论:轶为最大匹配的两倍。
秩相当于选一个最大的满秩的子矩阵。考虑子矩阵的行列式,一个有贡献的排列相当于找若干条有向边,使得每个点入度出度最大等于 1.
这个东西相当于最大匹配。因为这是一棵树,这个东西是唯一的,行列式的值不会被抵消掉
所以这个邻接矩阵的秩等于最大匹配。
于是 DP 每个点与其儿子匹配的概率。
#include<bits/stdc++.h>
using namespace std;
int getint(){
int ans=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
ans=ans*10+c-'0';
c=getchar();
}
return ans*f;
}
const int N=5e5+10,mod=998244353,inv2=(mod+1)/2;
struct bian{
int e,n;
};
bian b[N<<1];
int s[N],tot=0;
void add(int x,int y){
tot++;
b[tot].e=y;
b[tot].n=s[x];
s[x]=tot;
}
int f[N];
void ss(int x,int fa){
f[x]=1;
for(int i=s[x];i;i=b[i].n){
int v=b[i].e;
if(v==fa)continue;
ss(v,x);
f[x]=f[x]*(f[v]+1ll)%mod*inv2%mod;
}
f[x]=(mod+1-f[x])%mod;
}
int main(){
int n=getint(),p2=1;
for(int i=0;i<n-1;i++){
int x=getint(),y=getint();
add(x,y);
add(y,x);
p2<<=1;
p2>=mod&&(p2-=mod);
}
ss(1,0);
long long s=0;
for(int i=1;i<=n;i++)s+=f[i];
cout<<s%mod*2*p2%mod;
return 0;
}