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
Output for Sample Input
3
4 2
5 0
6 4
Case 1: 6
Case 2: 1
Case 3: 15
题意:数学组合问题改编成费马小定理—>逆元组合 C(n,m) = n! / (m! * (n - m)! )
逆元:由费马小定理a ^ (p-1) = 1 (%p),两边同时除去a——a ^ (p-2) = a^-1 (%p),得a的逆元a^-1 = a ^ (p-2)。
数据不大,可以预先打个N的阶层表和逆元表
关于逆元,不了解的同学戳这里 :http://blog.csdn.net/WYK1823376647/article/category/6355998
#include<cstdio>
#include<algorithm>
using namespace std;
const int mod = 1000003;
const int KL = 1000011;
long long pa[KL],ma[KL];
int KSM(int a,int b,int kl) // 快速幂
{
long long ans = 1,cut = a % kl;
while(b){
if(b & 1)
ans = ans * cut % kl;
cut = cut * cut % kl;
b >>= 1;
}
return ans;
}
void init() // 预处理
{
pa[0] = 1;
for(int i = 1 ; i < mod ; i++) // 打个 N 的阶层表
pa[i] = i * pa[i - 1] % mod;
ma[0] = ma[1] = 1;
for(int i = 2 ; i < mod ; i++)
ma[i] = KSM(pa[i],mod - 2 ,mod); // 打个 N 的逆元表
}
int main()
{
int T,nl = 0,N,M,pl;
scanf("%d",&T);
init();
while(T--)
{
scanf("%d%d",&N,&M);
pl = N - M;
long long ans = pa[N];
long long sum = ma[M];
long long cut = ma[pl];
ans = (ans * sum % mod) * cut % mod;
printf("Case %d: %lld\n",++nl,ans);
}
return 0;
}