loghtoj-1067

来源:互联网 发布:dream it possible 编辑:程序博客网 时间:2024/05/29 19:31


1067 - Combinations
   PDF (English)StatisticsForum
Time Limit: 2 second(s)Memory Limit: 32 MB

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



这道题主要运用了,费马小定理  百度就会知道,费马小定理(Fermat Theory)是数论中的一个
重要定理,
其内容为: 假如p是质数,且gcd(a,p)=1,那么 a(p-1)≡1(mod p)。即:假如a是整数,p是质数,
且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1


#include<cstdio>#define LL long long#define M 1000003LL num[M];LL pre[M];void count()//每一个数的阶乘都对 M 取余 {LL i;num[0]=1;num[1]=1;for(i=2;i<M;++i){num[i]=num[i-1]*i%M;}}LL quickpow(LL a,LL b,LL p)//快速幂取余 {LL ans=1;while(b){if(b&1){ans=ans*a%p;}a=a*a%p;b>>=1;}return ans;} void init()//求出每一个阶乘的逆元 {pre[0]=1;pre[1]=1;LL i;for(i=2;i<M;++i){pre[i]=quickpow(num[i],M-2,M);}}int main(){count();init();LL t,n,k,test=1;scanf("%lld",&t);while(t--){scanf("%lld%lld",&n,&k);LL a=num[n];LL b=pre[k];LL c=pre[n-k];LL ant=(a%M*b%M*c%M)%M;printf("Case %lld: %lld\n",test++,ant);}return 0;}


0 0