Description
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)%mod;
由于数据较大,不能直接求解,采用逆元;
先看逆元:
乘法逆元
满足a*k≡A (mod p)的k值就是a关于p的乘法逆元。
为什么要有乘法逆元呢?
当我们要求(a/b) mod p的值,且a很大,无法直接求得a/b的值时,我们就要用到乘法逆元。
我们可以通过求b关于p的乘法逆元k,将a乘上k再模p,即(a*k) mod p。其结果与(a/b) mod p等价。
证:
根据b*k≡1 (mod p)有b*k=p*x+1。
k=(p*x+1)/b。
把k代入(a*k) mod p,得:
(a*(p*x+1)/b) mod p
=((a*p*x)/b+a/b) mod p
=[((a*p*x)/b) mod p +(a/b)] mod p
=[(p*(a*x)/b) mod p +(a/b)] mod p //p*[(a*x)/b] mod p=0
所以原式等于:(a/b) mod p
代码:
<pre name="code" class="cpp">#include<string.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define mod 1000003
#define LL long long
LL com[1000005];//存的是i的阶乘;
LL cob[1000005];//存的是i的阶乘的mod-2次幂;
LL pow(LL n,LL k)
{
LL base=n,ans=1;
while(k)
{
if(k%2==1)
ans=(ans*base)%mod;
base=(base*base)%mod;
k/=2;//写成k>>1,竟然超时;
}
return ans;
}
void f()
{
int i=0;
com[0]=cob[0]=1;
for(i=1;i<=1000005;i++)
{
com[i]=(com[i-1]*i)%mod;
cob[i]=pow(com[i],mod-2);
}
}
int main()
{
int t,n,k,m=1;
f();
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
if(k>n/2)
k=n-k;
LL ans=com[n]*cob[k]%mod*cob[n-k]%mod;
printf("Case %d: %lld\n",m++,ans);
}
return 0;
}