HDU 5793-A Boring Question(数学化简,快速幂,逆元)

HDU 5793-A Boring Question

本篇文章部分参考

[https://www.cnblogs.com/Sunshine-tcf/p/5737627.html]

题目原址

[http://acm.hdu.edu.cn/showproblem.php?pid=5793]

题意

给你两个数 n m ,求解它们带入公式后的答案。

题解

公式十分复杂,刚开始甚至没看懂是什么意思,但知道需要找规律或者化简
后来去看了一下其他博客的题解(链接在上),找到了官方题解,果真是化简,就是有点点复杂。。。
HDU 5793A官方题解图

  1. 公式本身:本质上是很多个(懒得想多少个) m 个组合数的乘积 的和,给出样例的表达
    f ( x ) = C k 2 k 1 ⋅ C k 3 k 2 ( k 1 = 0 , k 2 = 0 , k 3 = 0 ) + C k 2 k 1 ⋅ C k 3 k 2 ( k 1 = 1 , k 2 = 0 , k 3 = 0 ) + C k 2 k 1 ⋅ C k 3 k 2 ( k 1 = 0 , k 2 = 1 , k 3 = 0 ) + f(x)=C_{k_{2}}^{k_{1}}\cdot{C_{k_{3}}^{k_{2}}}_{(k_{1}=0,k_{2}=0,k_{3}=0)}+C_{k_{2}}^{k_{1}}\cdot{C_{k_{3}}^{k_{2}}}_{(k_{1}=1,k_{2}=0,k_{3}=0)}+C_{k_{2}}^{k_{1}}\cdot{C_{k_{3}}^{k_{2}}}_{(k_{1}=0,k_{2}=1,k_{3}=0)}+ f(x)=Ck2k1Ck3k2(k1=0,k2=0,k3=0)+Ck2k1Ck3k2(k1=1,k2=0,k3=0)+Ck2k1Ck3k2(k1=0,k2=1,k3=0)+ C k 2 k 1 ⋅ C k 3 k 2 ( k 1 = 1 , k 2 = 1 , k 3 = 0 ) + C k 2 k 1 ⋅ C k 3 k 2 ( k 1 = 0 , k 2 = 0 , k 3 = 1 ) + C k 2 k 1 ⋅ C k 3 k 2 ( k 1 = 1 , k 2 = 0 , k 3 = 1 ) + C_{k_{2}}^{k_{1}}\cdot{C_{k_{3}}^{k_{2}}}_{(k_{1}=1,k_{2}=1,k_{3}=0)}+C_{k_{2}}^{k_{1}}\cdot{C_{k_{3}}^{k_{2}}}_{(k_{1}=0,k_{2}=0,k_{3}=1)}+C_{k_{2}}^{k_{1}}\cdot{C_{k_{3}}^{k_{2}}}_{(k_{1}=1,k_{2}=0,k_{3}=1)}+ Ck2k1Ck3k2(k1=1,k2=1,k3=0)+Ck2k1Ck3k2(k1=0,k2=0,k3=1)+Ck2k1Ck3k2(k1=1,k2=0,k3=1)+ C k 2 k 1 ⋅ C k 3 k 2 ( k 1 = 0 , k 2 = 1 , k 3 = 1 ) + C k 2 k 1 ⋅ C k 3 k 2 ( k 1 = 1 , k 2 = 1 , k 3 = 1 ) C_{k_{2}}^{k_{1}}\cdot{C_{k_{3}}^{k_{2}}}_{(k_{1}=0,k_{2}=1,k_{3}=1)}+C_{k_{2}}^{k_{1}}\cdot{C_{k_{3}}^{k_{2}}}_{(k_{1}=1,k_{2}=1,k_{3}=1)} Ck2k1Ck3k2(k1=0,k2=1,k3=1)+Ck2k1Ck3k2(k1=1,k2=1,k3=1)但其实可以发现,当且仅当 k 1 , k 2 , k 3 k_{1},k_{2},k_{3} k1,k2,k3广义降序的时候乘积和不为0,上面式子可以删去一些项得到 C k 2 k 1 ⋅ C k 3 k 2 ( k 1 = 0 , k 2 = 0 , k 3 = 0 ) + C k 2 k 1 ⋅ C k 3 k 2 ( k 1 = 0 , k 2 = 0 , k 3 = 1 ) + C k 2 k 1 ⋅ C k 3 k 2 ( k 1 = 0 , k 2 = 1 , k 3 = 1 ) + C k 2 k 1 ⋅ C k 3 k 2 ( k 1 = 1 , k 2 = 1 , k 3 = 1 ) C_{k_{2}}^{k_{1}}\cdot{C_{k_{3}}^{k_{2}}}_{(k_{1}=0,k_{2}=0,k_{3}=0)}+C_{k_{2}}^{k_{1}}\cdot{C_{k_{3}}^{k_{2}}}_{(k_{1}=0,k_{2}=0,k_{3}=1)}+C_{k_{2}}^{k_{1}}\cdot{C_{k_{3}}^{k_{2}}}_{(k_{1}=0,k_{2}=1,k_{3}=1)}+C_{k_{2}}^{k_{1}}\cdot{C_{k_{3}}^{k_{2}}}_{(k_{1}=1,k_{2}=1,k_{3}=1)} Ck2k1Ck3k2(k1=0,k2=0,k3=0)+Ck2k1Ck3k2(k1=0,k2=0,k3=1)+Ck2k1Ck3k2(k1=0,k2=1,k3=1)+Ck2k1Ck3k2(k1=1,k2=1,k3=1)既然是要广义降序,那么公式本身就可以化简为
    ∑ 0 ≤ k 1 , k 2 , ⋅ ⋅ ⋅ k m ≤ n ∏ 1 ≤ j &lt; m C k j + 1 k j = ∑ k m = 0 n ∑ k m − 1 = 0 k m ⋅ ⋅ ⋅ ∑ k 1 = 0 k 2 ∏ 1 ≤ j &lt; m C k j + 1 k j \sum_{{0}\leq{k_{1}},k_{2},\cdot\cdot\cdot{k_{m}}\leq{n}}\prod_{1\leq{j}&lt;m}C_{k_{j+1}}^{k_{j}}=\sum_{k_{m}=0}^{n}\sum_{k_{m-1}=0}^{k_{m}}\cdot\cdot\cdot\sum_{k_{1}=0}^{k_{2}}\prod_{1\leq{j}&lt;m}C_{k_{j+1}}^{k_{j}} 0k1,k2,kmn1j<mCkj+1kj=km=0nkm1=0kmk1=0k21j<mCkj+1kj
  2. 巧提公因式:很显然,前面的几项如 k m , k m − 1 k_{m},k_{m-1} km,km1确定后,后面的每项联乘中的 C k m k m − 1 C_{k_{m}}^{k_{m-1}} Ckmkm1都确定了,那么就可以单独提出来,用样例做示例:
    C k 3 k 2 ( k 2 = 0 , k 3 = 0 ) ( C k 2 k 1 ( k 1 = 0 ) ) + C k 3 k 2 ( k 2 = 0 , k 3 = 1 ) ( C k 2 k 1 ( k 1 = 0 ) ) + C k 3 k 2 ( k 2 = 1 , k 3 = 1 ) ( C k 2 k 1 ( k 1 = 0 ) + C k 2 k 1 ( k 1 = 1 ) ) {C_{k_{3}}^{k_{2}}}_{(k_{2}=0,k_{3}=0)}({C_{k_{2}}^{k_{1}}}_{(k_{1}=0)})+{C_{k_{3}}^{k_{2}}}_{(k_{2}=0,k_{3}=1)}({C_{k_{2}}^{k_{1}}}_{(k_{1}=0)})+{C_{k_{3}}^{k_{2}}}_{(k_{2}=1,k_{3}=1)}({C_{k_{2}}^{k_{1}}}_{(k_{1}=0)}+{C_{k_{2}}^{k_{1}}}_{(k_{1}=1)}) Ck3k2(k2=0,k3=0)(Ck2k1(k1=0))+Ck3k2(k2=0,k3=1)(Ck2k1(k1=0))+Ck3k2(k2=1,k3=1)(Ck2k1(k1=0)+Ck2k1(k1=1))对于公式来说,提公因式后:
    ∑ k m = 0 n ∑ k m − 1 = 0 k m ( C k m k m − 1 ∑ k m − 2 = 0 k m − 1 ( C k m − 1 k m − 2 ⋅ ⋅ ⋅ ( ∑ k 1 = 0 k 2 C k 2 k 1 ) ⋅ ⋅ ⋅ ) ) \sum_{k_{m}=0}^{n}\sum_{k_{m-1}=0}^{k_{m}}(C_{k_{m}}^{k_{m-1}}\sum_{k_{m-2}=0}^{k_{m-1}}(C_{k_{m-1}}^{k_{m-2}}\cdot\cdot\cdot(\sum_{k_{1}=0}^{k_{2}}C_{k_{2}}^{k_{1}})\cdot\cdot\cdot)) km=0nkm1=0km(Ckmkm1km2=0km1(Ckm1km2(k1=0k2Ck2k1)))所以我觉得上面的官方图解有点小瑕疵?我也不深究了,接下来可以发现最内项为 2 k 2 2^{k_{2}} 2k2,化简成:
    ∑ k 2 = 0 k 3 C k 3 k 2 ⋅ 2 k 2 = 3 k 3 \sum_{k_{2}=0}^{k_{3}}C_{k_{3}}^{k_{2}}\cdot2^{k_{2}}=3^{k_{3}} k2=0k3Ck3k22k2=3k3如此下去直到:
    ∑ k m = 0 n m k m = 1 + m 1 + m 2 + ⋅ ⋅ ⋅ + m n = m n + 1 − 1 m − 1 \sum_{k_{m}=0}^{n}m^{k_{m}}=1+m^{1}+m^{2}+\cdot\cdot\cdot+m^{n}=\frac{m^{n+1}-1}{m-1} km=0nmkm=1+m1+m2++mn=m1mn+11简洁得不行,用快速幂算一下分子,算一下分母的逆元即可。

实现

#include <stdio.h>
typedef long long ll;
int i, j, k;
int x, y;
const int mod = (int)1e9 + 7;
ll q_pow(int a, int b) {
    ll ans = 1;
    ll p = a;
    while (b) {
        if (b & 1)
            ans = ans * p%mod;
        p = p * p%mod;
        b >>= 1;
    }
    return ans;
}
int inv(int a,int b,int&x,int&y) {
    if (b == 0) {
        x = 1; y = 0;
        return a;
    }
    int ans = inv(b, a%b, y, x);
    y -= a / b * x;
    return ans;
}
ll solve(int n, int m) {
    ll ans = 1;
    inv(m - 1, mod, x, y);
    x = ((x%mod) + mod) % mod;//将x化为最小非负整数解
    ans = (q_pow(m, n + 1) - 1)*x % mod;
    return ans;
}
int main() {
    int t, n, m;
    scanf("%d", &t);
    while (t--) {
        scanf("%d%d", &n, &m);
        printf("%lld\n", solve(n, m));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值