题解:AT_agc073_c [AGC073C] Product of Max of Sum of Subtree
题目大意
有一棵
对于每个点
定义这棵树的贡献为,若
求贡献的期望。
解法
为了区分取值范围与点数,设取值范围为
先考虑一个弱化问题:若整棵树的
不妨设整棵树的
设
因为一种随机方案与一种
简单化简一下:
再考虑原问题。
容易发现,我们可以把树分为许多值相同的联通块,对于一个联通块可以用上述方法去做,且可以做到联通块之间互不影响。
若两点
然后就可以在树上 dp 了。
设
转移是平凡的,由于所有联通块大小的和一定为 dp 完后再乘上
时间复杂度
::::info[Code]
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e3+10;
const int p=998244353;
int n,m,inv[100010];
int f[N][N],sz[N],h[N];
vector<int> g[N];
int mo(int x){return x>=p?x-p:x;}
void add(int&x,int y) {x=mo(x+y);}
int ksm(int a,int b){
int ans=1;
for(;b;b>>=1,a=a*a%p) if(b&1) ans=ans*a%p;
return ans;
}
void dfs(int x,int fa){
sz[x]=1;
f[x][1]=1;
for(int v:g[x]){
if(v==fa) continue;
dfs(v,x);
for(int i=1;i<=sz[x];i++)
for(int j=0;j<=sz[v];j++)
add(h[i+j],f[x][i]*f[v][j]%p);
sz[x]+=sz[v];
for(int i=1;i<=sz[x];i++) f[x][i]=h[i],h[i]=0;
}
for(int i=1;i<=sz[x];i++) add(f[x][0],f[x][i]*inv[i*2]%p);
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n;
inv[1]=1;
for(int i=2;i<=n*2;i++) inv[i]=(p-p/i)*inv[p%i]%p;
for(int i=1,x,y;i<n;i++) cin>>x>>y,g[x].push_back(y),g[y].push_back(x);
dfs(1,0);
cout<<f[1][0]*ksm(ksm(n,n),p-2)%p<<"\n";
return 0;
}
::::