给定一个多项式(ax+by)^k,请求出多项式展开后x^ny^m项的系数。
输入描述:
共一行,包含5个整数,分别为a,b,k,n,m,每两个整数之间用一个空格隔开。
输出描述:
输出共1行,包含一个整数,表示所求的系数,这个系数可能很大,输出对10007取模后的结果。
示例1
输入
1 1 3 1 2
输出
3
备注:
对于30%的数据,有0≤k≤10; 对于50%的数据,有a=1,b=1; 对于100%的数据,有0≤k≤1,000,0≤n,m≤k,且n+m=k,0≤a,b≤1,000,000。
这里求的是系数,这里a一定和x对应,b一定和y对应,就相当于在k个(ax+by)中选n个x,剩下的就是m个y了,
所以这里的公式就是
而后边的这里可以用逆元来求
=k(k-1)(k-2)......(k-n+1)/1*2*3......*n
对于正整数和
,如果有
,那么把这个同余方程中
的最小正整数解叫做
模
的逆元。
逆元一般用扩展欧几里得算法来求得,如果为素数,那么还可以根据费马小定理得到逆元为
。
推导过程如下
所以这里求组合数的时候可以把所有的除法都变成乘法
求组合数:
n<=1000 递推公式 ![](https://i-blog.csdnimg.cn/blog_migrate/9b469931f9edeaa150b143ad2c46b643.png)
n<=100000 逆元
n<=10^18 Lucas定理
#include<iostream>
using namespace std;
long long mod=10007;
long long Mood(long long a,long long b){
long long sum=1;
a%=mod;
while(b){
if(b&1)
sum=sum*a%mod;
a=a*a%mod;
b=b>>1;
}
return sum;
}
int a,b,k,n,m;
long long ans=0;
int main(){
cin>>a>>b>>k>>n>>m;
ans=Mood(a,n)*Mood(b,m)%mod;
for(int i=1,j=k;i<=n;i++,j--){//逆元
ans=ans*j%mod;
ans=ans*Mood(i,mod-2)%mod;
}
cout<<ans<<endl;
return 0;
}