码迷,mamicode.com
首页 > 其他好文 > 详细

P1313 计算系数

时间:2018-10-10 23:39:19      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:处理   span   fine   math   快速幂   递推   答案   cst   class   

数学很重要!!

dalao们扫这道题就说“二项式定理”。二项式定理是这个东西:

\[(x+y)^n=\sum_{i=0}^{n}{C_n^i \ x^i \ y^{n-i}}\]

应该没打错。真的没打错。

二项式定理当然不仅只满足于这些变量系数只为1的,只要系数扔进变量里面一起去乘方就可以了。

那么如何解决这道题?

其实答案就是这个东西(大胆猜想,打表证明):

\[C_k^n \times a^n \times b^m\]

上面的组合数可以换成\(C_k^m\),意义相同。因为\(n+m=k\)

如何算得组合数?简单点的话你可以通过杨辉三角来\(O(k^2)\)的来边递推边取膜得到。

或者你可以像我这样,通过预处理阶乘,通过组合数的定义式\(C_m^n=\frac{m!}{n!(m-n)!}\)来得到。

注意:膜意义下没有除法,所以你要算乘法逆元。用费马小定理就能算出来了。

然后中间过程可能爆int,直接开long long,不用龟速乘,用快速幂就能够搞出来了。

讲道理我一点题解都没看。

代码:

#include<cstdio>

const int maxn = 1005;
const int mod = 10007;
#define ll long long
ll a, b, k, n, m;
ll frac[maxn];
ll pow_mod(ll x, ll y, ll z)
{
    ll ans = 1, base = x;
    while(y)
    {
        if(y & 1) ans = ans * base % z;
        base = base * base % z;
        y >>= 1;
    }
    return ans % z;
}
ll inv(ll x, ll p)
{
    return pow_mod(x, p - 2, p);
}
int main()
{
    scanf("%lld%lld%lld%lld%lld", &a, &b, &k, &n, &m);
    frac[0] = 1;
    for(int i = 1; i <= k; i++) frac[i] = frac[i - 1] * i % mod;
    ll zuheshu = frac[k] * inv(frac[n], mod) % mod * inv(frac[k - n], mod) % mod;
    ll a_n = pow_mod(a, n, mod);
    ll b_m = pow_mod(b, m, mod);
    ll ans = zuheshu * a_n % mod * b_m % mod;
    printf("%lld\n", ans);
    return 0;
}

P1313 计算系数

标签:处理   span   fine   math   快速幂   递推   答案   cst   class   

原文地址:https://www.cnblogs.com/Garen-Wang/p/9769401.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!