LightOJ 1067 组合数取模

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

一开始只知道很大  然后就一直优化   最后还是wa   后来才知道是一个数学公式

a/b%mod=a*(b^(mod-2))%mod  表示a乘b的(mod-2)次方      mod是素数

即s[n]/(s[n-m]*s[m])%mod==s[n]*pow(s[n-m],mod-2)*pow(s[m],mod-2)%mod   因为幂比较大   所以要用大指数幂的公式

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<math.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 1000006
#define mod 1000003
#define LL long long
LL s[N];
int pow_mod(LL a,int b)
{
    LL c=1;
    while(b)
    {
        if(b&1) c=c*a%mod;
        b=b/2;
        a=a*a%mod;
    }
    return (int)c;
}
void q()
{
    s[0]=1;
    for(int i=1;i<N;i++)
        s[i]=s[i-1]*i%mod;
}
int qq(int n,int m)
{
    LL ans=1;
    ans=s[n]*pow_mod(s[n-m],mod-2)%mod*pow_mod(s[m],mod-2)%mod;
    return (int)ans;
}
int main()
{
    int T,n,m,t=1;
    q();
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        printf("Case %d: %d
",t++,qq(n,m));
    }
    return 0;
}
原文地址:https://www.cnblogs.com/a719525932/p/5748574.html