牛客练习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 }

 

posted @ 2018-08-02 11:24  LeeSongt  阅读(247)  评论(0编辑  收藏  举报