组合数/Lucas定理
//组合数公式
LLI Combination(LLI n, LLI m) { //求(n,m)
LLI a = 1, b = 1;
for (LLI i = n; i > n - m; i--) a = a * i;
for (LLI i = m; i > 0; i--) b = b * i;
return a / b;
}
//还有组合数递推公式C(n,m) = C(n – 1,m) + C(n – 1,m - 1);
//C(n,m)的奇偶性判定
//C(n,m)的奇偶性取决于m和n-m的二进制表达式中是否存在同一位上的两个数码都是1。存在:偶,否则奇;
bool Odd_or_Even(int n,int m){ //偶数为true
return m & (n - m) ? true : false;
}
//Lucas定理(求大C(n,m) % p(p为素数))
LLI Comb(LLI n,LLI m,LLI p) {
if(n < m) return 0;
if(n == m) return 1;
m = min(n - m,m);
LLI ans = 1,cn = 1,cm = 1;
for(LLI i = 0; i < m; ++ i) {
cn = (cn * (n - i)) % p;
cm = (cm * (m - i)) % p;
}
ans = (cn * Fast_power(cm,p - 2,p)) % p;//调用快速幂函数,p18
return ans;
}
LLI Lucas(LLI n,LLI m,LLI p) {//求C(n,m) % p
LLI ans = 1;
while(n && m && ans) {
ans = (ans * Comb(n % p,m % p,p)) % p;
n = n / p;
m = m / p;
}
return ans;
}