求C ( m, n ) % p;
第一种 当n比较小的情况 n<1e5
一般用杨辉三角打表计算
原理:
C(n,m)=C(n-1,m)+C(n-1,m-1);
代码省略
第二种 当n 为 long long 时 用Lucas 定理
C(n,m) % p = (C(n % p, m % p) * Lucas( n / p, m / p )) % p。
(递归出口为m==0,return 1)
代码:
typedef long long ll;
const int mod = 1000000009;
ll quickpow(ll a, ll b) { //费马小定理求逆元
if (b < 0) return 0;
ll ret = 1;
a %= mod;
while(b) {
if (b & 1) ret = (ret * a) % mod;
b >>= 1;
a = (a * a) % mod;
}
return ret;
}
ll inv(ll a) {
return quickpow(a, mod - 2);
}
//计算组合数取模
ll comp(ll a, ll b, int p) {
if(a < b) return 0;
if(a == b) return 1;
if(b > a - b) b = a - b;
int ans = 1, ca = 1, cb = 1;
for(ll i = 0; i < b; ++i) {
ca = (ca * (a - i))%p;
cb = (cb * (b - i))%p;
}
ans = (ca*inv(cb)) % p;
return ans;
}
ll lucas(ll n, ll m, ll p) {
ll ans = 1;
while(n&&m&&ans) {
ans = (ans*comp(n%p, m%p, p)) % p;
n /= p;
m /= p;
}
return ans;
}}
第三种 当n 更大时 一般用 Java 计算
例题:
http://icpc.upc.edu.cn/problem.php?cid=1421&pid=8
1≤N<1040,0≤M≤1000。
代码:
import java.math.BigInteger;
import java.math.BigDecimal;
import java.util.*;
public class Main {
public static void main(String[] args)
{
Scanner cin = new Scanner (System.in);
int n, m;
BigInteger a, b;
n = cin.nextInt();
m = cin.nextInt();
n--;
m--;
a = BigInteger.ONE;
for(int i = n + 1; i <= n+m; i++){
b = BigInteger.valueOf(i);
a = a.multiply(b);
}
for(int i = 1; i <= m; i++){
b = BigInteger.valueOf(i);
a = a.divide(b);
}
System.out.println(a);
}
}