51nod1632-推公式&快速幂-B君的连通

来源:互联网 发布:什么值得买 类似 知乎 编辑:程序博客网 时间:2024/06/01 22:38

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;}
原创粉丝点击