1632 B君的连通 51NOD1632 【公式+快速幂】

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

最优的情况是一条路也不炸毁,这样有n个城市相连,最坏的情况是炸毁n-1条路,只有本身;

选择n条边的几率是(1/2)^(n-1),最后还要乘2^(n-1),所以抵消;

所以得到个公式  1*c(0,n-1)+2*c(1,n-1)+3*(2,n-1).........n*(n-1,n-1);

然后化简得到  res[i]=res[i-1]*2+2^(i-2)  (模仿网上的大牛)

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<queue>
#include<math.h>
#include<map>
#include<vector>
#include<stack>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int N=1e5+5;

ll ans[N];

ll power(ll b,ll a)//快速幂
{
    ll res=1;
    while(b>0)
    {
        if(b%2==1)
            res=res*a%mod;
        a=a*a%mod;
        b/=2;
    }
    return res%mod;
}

int main()
{
    ll i,j,n;
    int a,b;
    scanf("%lld",&n);
    for(i=0;i<n-1;i++)
        scanf("%d %d",&a,&b);
    ans[1]=1;
    for(i=2;i<=n;i++)
        ans[i]=(ans[i-1]*2%mod+power(i-2,2))%mod;
    printf("%lld\n",ans[n]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41984014/article/details/82532678