Codeforces Round #539 (Div.2): F-Sasha and Interesting Fact from Graph Theory(计数+扩展凯利公式)

题目链接:http://codeforces.com/contest/1113/problem/F

题意:现在有一棵树,树有n个节点,每条边有一个权值,权值最大为m,现在给你两个点a, b,两点间路径的权值和是m,现在问你这棵树有多少种组成方式。

解题心得:现在假设两点间有e条边,那么就有e-1个点

  1. 从n-2个点中选点出来在两点间的组合方式是A(n-2, e-1)种组合方式。
  2. 两点间的e-1个点权值的安排方式按照隔板法有C(e-1, m-1)种。
  3. 剩下的n-e-1个点要放在已经组合好的这个路径上根据凯利公式有:(e+1)*n^(n-i-2)种方式。
  4. 以上三种组合乘起来就是e条边的答案。

枚举两点间边的数目,然后将所有方法加起来,里面要取模还需要逆元等知识。

#include <bits/stdc++.h>

using namespace std;
const int maxn = 1e6 + 100;
const int MOD = 1e9 + 7;
typedef long long ll;

ll n, m, a, b;
ll mult[maxn];

void pre() {
    mult[0] = 1;
    for (ll i = 1; i < maxn; i++) {
        mult[i] = (mult[i - 1] * i) % MOD;
    }
}

ll q_pow(ll x, ll cnt) {
    ll ans = 1;
    x %= MOD;
    if (x == 0) return 1;
    while (cnt) {
        if (cnt & 1) ans = (ans * x) % MOD;
        x = (x * x) % MOD;
        cnt >>= 1;
    }
    return ans;
}

int main() {
    freopen("1.in", "r", stdin);
    pre();
    while (scanf("%lld%lld%lld%lld", &n, &m, &a, &b) != EOF) {

        ll ans = 0;
        for (ll i = 1; i <= min(m, n - 1); i++) {
            //A(i-1, n-2)
            ll temp1 = mult[n - 2] * q_pow(mult[n - i - 1], MOD - 2) % MOD;

            //C(i-1, m-1)
            ll temp2 = mult[m - 1] % MOD * q_pow(mult[m - i], MOD - 2) % MOD * q_pow(mult[i - 1], MOD - 2) % MOD;

            //m^(n-i-1)
            ll temp3 = q_pow(m, n - i - 1) % MOD;

            //(i+1)*n^(n-i-2)
            ll temp4 = (i + 1) % MOD * (n -i - 2 < 0 ? q_pow(q_pow(n, -(n - i - 2)), MOD - 2) : q_pow(n, n - i - 2)) % MOD;

            ans = ans + temp1 * temp2 % MOD * temp3 % MOD * temp4 % MOD;
        }
        printf("%lld\n", ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值