原题链接:
Given n different objects, you want to take k of them. How many ways to can do it?
For example, say there are 4 items; you want to take 2 of them. So, you can do it 6 ways.
Take 1, 2
Take 1, 3
Take 1, 4
Take 2, 3
Take 2, 4
Take 3, 4
Input
Input starts with an integer T (≤ 2000), denoting the number of test cases.
Each test case contains two integers n (1 ≤ n ≤ 106), k (0 ≤ k ≤ n).
Output
For each case, output the case number and the desired value. Since the result can be very large, you have to print the result modulo 1000003.
Sample Input
3
4 2
5 0
6 4
Sample Output
Case 1: 6
Case 2: 1
Case 3: 15
题意:
计算组合数C(n,m),最后求余1000003的结果
题解:
如果利用公式直接算阶乘的话,结果会很大。这里要用到同余定理,但是除法不能使用同余定理,所以要把分母转换为其逆元,再利用乘法同余定理计算即可。
中间计算逆元时可以利用快速幂。
附上AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define LL long long
const int N=1000005;
const int mod=1000003;
LL a[N],b[N];
LL quickpow(LL a,LL b)//快速幂
{
LL ans=1;
while(b)//一层一层的算
{
if(b&1) ans=(ans*a)%mod;//如果b的二进制最右端是1
a=(a*a)%mod;
b>>=1;
}
return ans;
}
int main()
{
a[0]=1,b[0]=1;
for(int i=1;i<=N;++i)
{
a[i]=(a[i-1]*i)%mod;
b[i]=quickpow(a[i],mod-2);//费马小定理
}
int t,n,k;
scanf("%d",&t);
for(int cas=1;cas<=t;cas++)
{
scanf("%d%d",&n,&k);
LL ans=((a[n]*b[k]%mod)*b[n-k])%mod;//同余
printf("Case %d: %lld\n",cas,ans);
}
return 0;
}
欢迎评论!