标签:ide 图片 show open 直接 代码 long == text
首先这个题要明白一个东西:a/b+a/c≡a*(inv[b]+inv[c]) (mod p)。
这个题暴力就可以做。
题目要求期望,那么我们可以求每种可能的概率,然后相乘,就得到期望。
对于每个节点,枚举它的每个儿子作为重链,然后再枚举所有儿子的可能的轻链的条数,更新这个节点。
根据上面的式子,我们可以直接将概率 ”相加“ 而不用通分,
最后在root节点求一下期望。
丑陋的代码:
#include<iostream> #include<cstring> #include<cstdio> #include<vector> #define Maxn 3050 #define mod 1000000007 #define Inv(x) (mi((x),mod-2,mod)) #define Reg register using namespace std; int n,k,root,du[Maxn]; long long p[Maxn][Maxn],vis[Maxn][Maxn]; vector<vector<int> > son(Maxn),vp(Maxn); long long max(long long x,long long y) {return x>y?x:y;} long long mi(long long x,long long y,long long p) { long long ans=1,base=x; while(y) { if(y&1) ans=(ans*base)%p; base=(base*base)%p; y>>=1; } return ans; } void dfp(int x,int child,int zchi,long long cnt,long long poz) { if(child==son[x].size()) { p[x][cnt]=(p[x][cnt]+poz*Inv(son[x].size()))%mod; if(!vis[x][cnt]) { vis[x][cnt]=1; vp[x].push_back(cnt); } return; } int k=son[x][child]; for(Reg int i=0;i<vp[k].size();++i) { if(child!=zchi) dfp(x,child+1,zchi,max(cnt,vp[k][i]+1),(p[k][vp[k][i]]*poz)%mod); else dfp(x,child+1,zchi,max(cnt,vp[k][i]),(p[k][vp[k][i]]*poz)%mod); } return; } void dfs(int x) { // cout<<x<<endl; for(Reg int i=0;i<son[x].size();++i) dfs(son[x][i]); for(Reg int i=0;i<son[x].size();++i) //i是重儿子 概率1/son[x].size() dfp(x,0,i,0,1); if(!son[x].size()) { p[x][0]=1; vp[x].push_back(0); vis[x][0]=1; } return; } int main() { // freopen("text.in","r",stdin); scanf("%d",&n); for(Reg int i=1,k;i<=n;++i) { scanf("%d",&k); for(Reg int j=1,x;j<=k;++j) { scanf("%d",&x); son[i].push_back(x); ++du[x]; } } for(Reg int i=1;i<=n;++i) if(!du[i]) root=i; dfs(root); long long anp=0; for(Reg int i=0;i<vp[root].size();++i) anp=(anp+p[root][vp[root][i]]*vp[root][i])%mod; printf("%lld",anp); return 0; }
标签:ide 图片 show open 直接 代码 long == text
原文地址:https://www.cnblogs.com/Milk-Feng/p/11187965.html