组合数求解

扩展欧几里得算法原理
求解逆元的方法(本文采用扩展欧几里得算法进行求解)
求组合数的两种方法
Lucas定理

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>


using namespace std;

// 扩展欧几里得算法求方程ax+by=gcd(a,b)的一个解
// 返回a,b的最大公约数 
int exGcd(int a, int b, int &x, int &y){
    if(b == 0){
        x = 1;
        y = 0;
        return a;
    }
    int g = exGcd(b, a % b, x, y);
    int temp = x;
    x = y;
    y = temp - a / b * y;
    return g;
}
//求解a模m的逆元的最小整数解 
int inverse(int a, int m){
    int x, y;
    int g = exGcd(a, m, x, y);
    return (x % m + m) % m;
}
//n中选m的组合数,对p取余的结果 
int Cal(int n, int m, int p){
    int res = 1;
    for(int i = 1; i <= m; i++){
        res = res * (n - m + i) % p;
        res = res * inverse(i, p) % p;
    }
    return res;
}
//Lucas定理求解组合数 
int Lucas(int n, int m, int p){
    if(m == 0)
        return 1;
    int C = Cal(n % p, m % p, p);
    return C * Lucas(n / p, m / p, p) % p;
} 

int main(){
    int n, m, p;
    while(scanf("%d%d%d", &n, &m, &p) != EOF){
        printf("%d\n", Lucas(n, m, p));
    }
    return 0;
}



©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本章涉及知识点1、素数的定义2、寻找素数算法—短除法3、寻找素数算法—筛选法4、互质关系5、欧拉函数的证明6、欧拉...
    PrivateEye_zzy阅读 4,618评论 0 6
  • 引言 昨日看到几个关键词:语义分析,协同过滤,智能推荐,想着想着便兴奋了。于是昨天下午开始到今天凌晨3点,便研究了...
    Alukar阅读 1,626评论 1 14
  • AI人工智能时代,机器学习,深度学习作为其核心,本文主要介绍机器学习的基础算法,以详细线介绍 线性回归算法 及其 ...
    erixhao阅读 13,956评论 0 36
  • 关于使用python实现RSA加密解密 一、非对称加密算法 1、乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何...
    ttaymm阅读 958评论 0 0
  • 空间想象力开始凸显的一周! 再也不是简单叠加,开始有丰富的造型啦! 这汉堡是我刚进门稻稻就拿过来给我吃哒!真乖,知...
    小稻小秋的妈妈阅读 133评论 0 0