牛客练习23 托米的游戏
1 /* 2 题意:给出一个树,根是1,每次选一个节点删除,求期望删空的步数e = a/b, 求x使得(xb = a) % 998244353. 3 题解:考虑每个节点对答案的贡献,一个节点i被删除时,对答案贡献1,而被删除的概率为1/dep[i]. 4 e = sum(1/dep[i]) = a/b, 5 由 (xb=a)%P => x=a*(b^-1) % P; b^-1 是模P下的逆元 6 于是x = sum(1*(dep[i]^-1)) % P; 7 时间:2018.08.02 8 */ 9 10 #include <bits/stdc++.h> 11 using namespace std; 12 13 typedef long long LL; 14 const int MAXN = 100005; 15 const LL MOD7 = 1e9+7; 16 const LL MOD717 = 7*17*(1<<23) + 1; 17 18 vector<int> g[MAXN]; 19 int depth[MAXN]; 20 int n; 21 22 void dfs(int u,int pre,int dep) 23 { 24 depth[u]=dep; 25 for (int v:g[u]) 26 { 27 if (v==pre) continue; 28 dfs(v,u,dep+1); 29 } 30 } 31 32 LL Pow(LL a, LL b, LL P) 33 { 34 LL res=1LL; 35 LL ans=a%P; 36 while (b) 37 { 38 if (b&1) res=res*ans%P; 39 ans=ans*ans%P; 40 b>>=1; 41 } 42 return res; 43 } 44 45 46 int main() 47 { 48 // cout<<MOD717<<endl; 49 #ifndef ONLINE_JUDGE 50 // freopen("test.txt","r",stdin); 51 #endif // ONLINE_JUDGE 52 int u,v; 53 while (scanf("%d",&n)!=-1) 54 { 55 for (int i=0;i<=n;++i) 56 { 57 g[i].clear(); 58 depth[i]=0; 59 } 60 for (int i=1;i<n;++i) 61 { 62 scanf("%d%d",&u,&v); 63 g[u].push_back(v); 64 g[v].push_back(u); 65 } 66 dfs(1, -1, 1); 67 LL ans=0; 68 for (int i=1;i<=n;++i) 69 { 70 ans = (ans + Pow(depth[i], MOD717-2, MOD717)) % MOD717; 71 } 72 printf("%lld\n",ans); 73 } 74 return 0; 75 }