https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1632
应该想一想他后面为什么要成pow(2,i-1)。
写一下期望公式。
就是推一下公式,然后打一个表找一下规律就行了,因为每炸毁一条边就多一个连通图,所以就根据这个推出公式,因为选一条边的概率是 1/2:然后进行操作的概率就是 (1/2)^n−1),然后再乘以 2^n−1 就抵消了,所以公式就是:
1+2∗C(n−1,1)+3∗C(n−1,2)+…+n∗C(n−1,n−1) (2,3是表示多少个联通块)
看的学长的博客qwq,自己没想到。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn = 100000+5;
ll quick_pow(ll a, ll b)
{ ll ans = 1;//快速幂。
while(b)
{
if(b & 1)
ans = (ans*a)%mod;
b>>=1;
a = (a*a)%mod;
}
return ans;
}
ll c[50][50];
void Init1()
{
for(int i=0; i<50; i++)
c[i][0] = 1;
for(int i=1; i<50; i++)
{
for(int j=1; j<=i; j++)
{
c[i][j] = c[i-1][j]+c[i-1][j-1];
}
}
}
void out(){
ll sum=0;
for(int j=1;j<=20;j++){
sum=0;
for(int i=0;i<j;i++){
sum+=c[j-1][i]*(i+1);
}
cout<<j<<" "<<sum<<endl;
}
}
ll ans[maxn];
void Init()
{ ans[1]=1;
for(int i=2;i<maxn;i++){
ans[i]=(ans[i-1]*2+quick_pow(2,i-2)%mod)%mod;
}
}
int main()
{
//Init1();
//out();
Init();
ll n, x, y;
while(cin>>n)
{
for(int i=0; i<n-1; i++)
cin>>x>>y;
cout<<ans[n]<<endl;
}
return 0;
}