1632 B君的连通

B国拥有n个城市,其交通系统呈树状结构,即任意两个城市存在且仅存在一条交通线将其连接。A国是B国的敌国企图秘密发射导弹打击B国的交通线,现假设每条交通线都有50%的概率被炸毁,B国希望知道在被炸毁之后,剩下联通块的个数的期望是多少?

 

Input
一个数n(2<=n<=100000)
接下来n-1行,每行两个数x,y表示一条交通线。(1<=x,y<=n)
数据保证其交通系统构成一棵树。
Output
一行一个数,表示答案乘2^(n-1)后对1,000,000,007取模后的值。
Input示例
3
1 2
1 3
Output示例
8

思路:每炸毁一条边就多出一个连通图,所以最优是一个连通,最差是n个连通。选择一条边的概率是1/2,选择n条边就是1/2^(n-1),那么最后题目要求乘以2^(n-1),所以抵消了。 然后就知道使用组合数来做啦,取模求逆元即可。复杂度(n*log(n));

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<queue>
 5 #include<math.h>
 6 #include<stdlib.h>
 7 using namespace std;
 8 typedef long long LL;
 9 const int mod = 1e9+7;
10 LL N[100005];
11 LL quick(LL n,LL m,LL p);
12 int main(void)
13 {
14     int n;
15     N[0] = 1;
16     for(int i = 1;i <= 100000 ;i++)
17     {
18         N[i] = N[i-1]*(LL)i % mod;
19     }
20     scanf("%d",&n);
21     int s = n-1;
22     while(s--)
23     {   int x,y;
24         scanf("%d %d",&x,&y);
25     }
26     if(n == 1)
27         printf("1\n");
28     else
29     {
30         LL sum = 1;
31         for(int i = 1;i <= n-1; i++)
32         {
33             LL ak = i+1;
34             LL ap = N[n-1-i]*N[i]%mod;
35             ap = quick(ap,mod-2,mod);
36             ap*=ak;
37             ap%=mod;
38             sum = (sum + N[n-1]*ap%mod)%mod;
39         }
40         printf("%lld\n",sum);
41     }return 0;
42 }
43 LL quick(LL n,LL m,LL p)
44 {
45     n%=p;
46     LL ans = 1;
47     while(m)
48     {
49         if(m&1)
50             ans = ans*n%mod;
51         n = n*n%mod;
52         m>>=1;
53     }
54     return ans;
55 
56 }

 

posted @ 2016-08-19 19:55  sCjTyC  阅读(285)  评论(0编辑  收藏  举报