Description
Given n differentobjects, you want to take k of them. How many ways to can do it?
For example, saythere 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 withan integer T (≤ 2000), denoting the number of test cases.
Each test casecontains 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 verylarge, 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,k)%1000003的结果
分析:根据公式C(n,k)=n!/((n-k)!*k!),可以先求出n!,(n-k)!和k!,利用费马小定理分别求出(n-k)!和k!的逆元:(1/(n-k)!)%mod=((n-k)!)^(mod-2)%mod,k!%mod=(k!)^(mod-2),然后即可得出结果。需要注意的是为了防止TLE需要预处理计算出1000000内的阶乘。下面附上AC代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1000005;
const int mod=1000003;
ll jie[maxn];
int n,k;
void f() //预处理求出1000000内阶乘,防TLE
{
jie[0]=1;
for(ll i=1;i<=1000000;i++)
jie[i]=(jie[i-1]*i)%mod;
}
int pow_mod(int a,int n,int m) //快速幂计算a^n%m
{
if(n==0) return 1;
int x=pow_mod(a,n/2,m);
ll ans=(ll)x*x%m;
if(n%2) ans=ans*a%m;
return (int)ans;
}
int main()
{
int T;
scanf("%d",&T);
int cnt=1;
f();
while(~scanf("%d%d",&n,&k))
{
if(k==0||k==n)
{
printf("Case %d: 1\n",cnt++);
continue;
}
if(k>n/2) k=n-k;
int p1=(int)jie[n],p2=(int)jie[n-k],p3=(int)jie[k];
p2=pow_mod(p2,mod-2,mod); p3=pow_mod(p3,mod-2,mod); //计算逆元
ll ans=((ll)p1*p2)%mod*p3%mod;
printf("Case %d: %d\n",cnt++,(int)ans);
}
return 0;
}