从 n 个不同元素中,任取 m(m \le n)m(m≤n) 个元素并成一组,叫做从 nn 个不同元素中取出 mm 个元素的一个组合;从 nn 个不同元素中取出 m(m \le n)m(m≤n) 个元素的所有组合的个数,叫做从 nn 个不同元素中取出 mm 个元素的组合数,记为 C_n^mCnm。
组合数的计算方法为 C_n^m = \frac{n!}{m!(n-m)!}Cnm=m!(n−m)!n!,其中 !! 表示阶乘。同时组合数还满足 C_{n}^{m} = C_{n-1}^{m-1} + C_{n - 1}^{m}Cnm=Cn−1m−1+Cn−1m 这个性质。
请你编程求解组合数 C_n^mCnm 的值,由于结果可能很大,输出结果对 1000000007 取模的结果。
输入格式
输入一行两个整数 n(1 \le n \le 2000), m(0 \le m \le n)n(1≤n≤2000),m(0≤m≤n)。
输出格式
输出 C_n^mCnm 对 1000000007 取模的结果。
Sample 1
Inputcopy | Outputcopy |
---|---|
5 2 | 10 |
Sample 2
Inputcopy | Outputcopy |
---|---|
100 50 | 538992043 |
#include<stdio.h>
typedef long long LL;
LL n,m,p=1000000007;
LL quick_mod(LL a,LL b)
{
LL ans=1;
a%=p;
while(b){
if(b&1){
ans=ans*a%p;
b--;
}
b>>=1;
a=a*a%p;
}
return ans;
}
LL c(LL n,LL m)
{
if(m>n) return 0;
LL ans=1;
for(int i=1;i<=m;i++){
LL a =(n+i-m)%p;
LL b=i%p;
ans=ans*(a*quick_mod(b,p-2)%p)%p;
}
return ans;
}
LL T1984(LL n,LL m)
{
if(m==0) return 1;
return c(n%p,m%p)*T1984(n/p,m/p)%p;
}
int main()
{
scanf("%lld%lld",&n,&m);
printf("%lld\n",T1984(n,m));
return 0;
}