计算系数(二项式定理&&逆元&&费马小定理)

给定一个多项式(ax+by)^k,请求出多项式展开后(x^n)*(y^m)项的系数。

输入格式

共一行,包含 5 个整数,分别为 a,b,k,n,m,每两个整数之间用一个空格隔开。

输出格式

输出共 1 行,包含一个整数,表示所求的系数,这个系数可能很大,输出对10007 取模后的结果。

数据范围

0≤n,m≤k≤1000,
n+m=k,
0≤a,b≤106

输入样例:

1 1 3 1 2 

输出样例:

3

解题步骤:

根据二项式定理:

得(x^n)*(y^m)的系数为:

所以只要根据这个公式,分别计算出其三部分,然后乘起来即可。

对于(a^n)*(b^m),可以直接采用快速幂来求。

对于C(n,k)=(k*(k-1)*(k-2)*...*(k-n+1))/(1*2*3*..*k),这个分式,首先用逆元将除法变为乘法,即:x/y=x*y的逆元

形如:A*x%p=1%p   (表示A关于p的逆元x)

根据费马小定理:a^(p-1)%p=1%p, (p为素数)

                       所以:(a^(p-2)*a)%p=1%p,这就转化成了A的逆元的形式,这里a相当于A,a^(p-2)就是a关于p的逆元

所以这里对于这个分式里的分母的每个数t转化成其逆元就是t^(p-2)=t^10005,用快速幂算出来,然后让分子和这些逆元累成起来就可以了。

完整代码:

#include <iostream>

using namespace std;

const int mod=1e4+7;

int a,b,k,n,m;

int qmi(int a,int b)
{
    a%=mod;
    int res=1;
    while(b){
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}

signed main()
{
    cin>>a>>b>>k>>n>>m;
    int res=qmi(a,n)*qmi(b,m)%mod;
    for(int i=1,j=k;i<=n;i++,j--){
        res=res*j%mod;
        res=res*qmi(i,mod-2)%mod;
    }
    cout<<res<<endl;
    return 0;
}
发布了176 篇原创文章 · 获赞 9 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Mr_Kingk/article/details/105588140