【zznu-2093】毁掉这颗二叉树

本文介绍了一道算法题,题目要求计算砍伐一棵拥有n个节点的二叉树后形成的联通块的期望数量。文章提供了一种解决方案,通过组合数学中的组合数计算公式,并使用逆元求解取模条件下的除法运算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【zznu-2093】毁掉这颗二叉树

题目描述

广寒宫下有株二叉树,树上共有n个节点,通过n-1条树枝连接,树下有一只玉兔,吴刚提着斧子站在一旁。

他恼恨一切同他争夺嫦娥的事物,所以他决定通过砍二叉树上的n-1条树枝来毁掉这颗二叉树。

妙的是,这些树枝只能被砍一次,而且被砍后有一半的概率立即长出。

吴刚砍了n斧子后罢手了,他打算“不眠倚桂树”。你来猜猜,现在这株二叉树有多少联通块?(即联通块的期望值)

已知:最后一斧子砍了玉兔。

输入

输入一个正整数T(1<=T<=50)

接下来T行,每行输入一个正整数n,代表二叉树的节点数,2<=n<=1e5。

 

输出

输出联通块的期望值,答案的数据可能很大,所以输出答案乘2^(n-1)后再对1e9+7取模

样例输入

1
2

样例输出

3

就是让求 1*C(n-1, 0) + 2*C(n-1, 1) + 3*C(n-1, 2) + ... + n*C(n-1, n-1) 的值

除法取余利用逆元求解,逆元可以用inv[i]=(mod-mod/i)*inv[mod%i]%mod线性求出。

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
typedef long long LL;
const LL mod = 1e9+7;
int inv[N];
int main()
{
    int t, n;
    inv[1] = 1;
    for(int i = 2; i <= 1e5; i++)
        inv[i]=(mod-mod/i)*inv[mod%i]%mod;
    cin>>t;
    while(t--)
    {
        scanf("%d", &n);
        LL ans = 1, temp = 1;
        for(int i = 2; i <= n; i++)
        {
            temp = temp*(n-i+1)%mod*inv[i-1]%mod;
            ans = (ans + i*temp) % mod;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

posted @ 2018-05-23 21:34 LesRoad 阅读(...) 评论(...) 编辑 收藏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值