数论——卢卡斯定理、求组合数 学习笔记

这篇具有很好参考价值的文章主要介绍了数论——卢卡斯定理、求组合数 学习笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

数论——卢卡斯定理、求组合数

说明

温馨提示:组合数一般较大,下面的示范代码均无视数据范围,如果爆 int 请自行开 long long 或高精度处理。

引入

\(n\) 个不同元素中,任取 \(m\) 个元素组成一个集合,叫做从 \(n\) 个不同元素中取出 \(m\) 个元素的一个组合;从 \(n\) 个不同元素中取出 \(m \leq n\) 个元素的所有组合的个数,叫做从 \(n\) 个不同元素中取出 \(m\) 个元素的组合数,也被称为「二项式系数」。

用符号 \(\dbinom{n}{m}\) 来表示,读作「\(n\)\(m\)」;组合数计算公式:\(\dbinom{n}{m} = \dfrac{n!}{m! \, (n - m)!}\)

特别地,规定当 \(m > n\) 时,\(\dbinom{n}{m}=0\)

组合数也常用 \(\mathrm C(n, m)\) 表示,即 \(\mathrm C(n, m) = \dbinom{n}{m}\)
但现在数学界普遍采用 \(\dbinom{n}{m}\) 的记号而非 \(\mathrm C(n, m)\)

性质

\[\binom{n}{m}=\binom{n}{n-m}\tag{1} \]

\(n\)\(m\),等价于从 \(n\) 个中挑出 \(n - m\) 个不选.

\[\binom{n}{m}=\binom{n-1}{m}+\binom{n-1}{m-1}\tag{2} \]

\(n\) 个是否选?若选,则 \(n - 1\)\(m - 1\);若不选,则选 \(m\) 个.

\[\sum_{i=0}^m \binom{n}{i}\binom{m}{m-i} = \binom{m+n}{m}\ \ \ (n \geq m)\tag{3} \]

\(n\)\(i\),另外 \(m\)\(m - i\);即 \(n + m\)\(m\).

\[\sum_{i=0}^n\binom{n}{i}^2=\binom{2n}{n}\tag{4} \]

\(n = m\) 时的 \((3)\).

\[\binom{n}{r}\binom{r}{k} = \binom{n}{k}\binom{n-k}{r-k}\tag{5} \]

\(n\)\(r\),再 \(r\)\(k\) 个;即 \(n\)\(k\),再有剩余的 \(n - k\)\(r - k\).

\[\binom{n}{m} \bmod p = \binom{n \bmod p}{m \bmod p}\binom{n / p}{m / p} \bmod p\tag{6} \]

这个就是卢卡斯定理,见下面~

卢卡斯定理

定义

定义:\(\displaystyle \binom{n}{m} \bmod p = \binom{n \bmod p}{m \bmod p}\binom{n / p}{m / p} \bmod p\).

其中 \(p\) 为质数;且当 \(p\) 较小时使用卢卡斯定理求解组合数较快.

代码实现

\(\mathrm{Lucas}(n, m) = \mathrm C(n \bmod p, m \bmod p) \times \mathrm{Lucas}(n / p, m / p) \bmod p\).

有递归版和非递归版:

int lucas(int a, int b, const int p)
{
    if (a < p && b < p)
        return comb(a, b, p);
    return comb(a % p, b % p, p) * lucas(a / p, b / p, p) % p;
}
int lucas(int a, int b, const int p, int r = 1)
{
    while (a >= p || b >= p)
        r = r * comb(a % p, b % p, p) % p, a /= p, b /= p;
    return r * comb(a, b, p) % p;
}

拓展应用

分析公式,很显然是将 \(n\)\(m\) 拆解为 \(p\) 进制的过程:

\(\displaystyle n = \prod_{i = 0}^r N_i \, p^k\)\(\displaystyle m = \prod_{i = 0}^r M_i \, p^k\),那么 \(\displaystyle \binom{n}{m} = \prod_{i = 1}^r \binom{N_i}{M_i}\).

如题:P6669 组合数问题(将问题通过卢卡斯定理转化为范围内数码的问题,并用数位 DP 求解)

点击查看代码
typedef long long ll;

const int N = 110;
const ll MOD = 1e9 + 7;

inline ll MUL(ll a, ll b) { return (a % MOD) * (b % MOD) % MOD; }

int t, k, r;
int a[N], b[N];

ll dp[N][2][2];
ll dfs(int now, bool ln, bool lm)
{
    if (!now) return 1;
    if (dp[now][ln][lm] != -1) return dp[now][ln][lm];
    ll res = 0;
    int upn = ln ? a[now] : k - 1, upm = lm ? b[now] : k - 1;
    for (int i = 0; i <= upn; ++i) for (int j = 0; j <= i && j <= upm; ++j)
        res = (res + dfs(now - 1, ln && i == upn, lm && j == upm)) % MOD;
    return dp[now][ln][lm] = res;
}

int main()
{
    t = rr, k = rr;
    while (t--)
    {
        memset(dp, -1, sizeof dp);

        ll n = rr, m = min(n, rr);
        ll rt = (MUL(m + 1, m + 2) * 500000004ll % MOD + MUL(n - m, m + 1)) % MOD;

        int r = 0, ra = 0;
        while (n) a[++r] = n % k, n /= k;
        while (m) b[++ra] = m % k, m /= k;
        while (ra < r) b[++ra] = 0;

        printf("%lld\n", (rt - dfs(r, 1, 1) + MOD) % MOD);
    }
    return 0;
}

求组合数

递推预处理所有组合数

公式:\(\dbinom{n}{m} = \dbinom{n - 1}{m} + \dbinom{n - 1}{m - 1}\).

点击查看题目

网址:https://www.acwing.com/problem/content/887/

const int N = 2010;
const long long MOD = 1e9 + 7;

long long comb[N][N];

int main()
{
    comb[0][0] = 1;
    for (int i = 1; i < N; ++i)
    {
        comb[i][0] = 1;
        for (int j = 1; j <= i; ++j)
            comb[i][j] = (comb[i - 1][j - 1] + comb[i - 1][j]) % MOD;
    }

    int t = rr, a, b;
    while (t--)
        a = rr, b = rr, printf("%lld\n", comb[a][b]);
    return 0;
}

预处理阶乘和逆元

定义式:\(\dbinom{n}{m} = \dfrac{n!}{m! \, (n - m)!}\).

可以每次都用费马小定理计算逆元,更好的方法是线性预处理逆元;
因此也需要保证模数 \(p > n, m\).

点击查看题目

网址:https://www.acwing.com/problem/content/888/

注意除去的是阶乘的逆元,所以不需要预处理单个数的逆元了.

const int N = 1e5 + 10;
const ll MOD = 1e9 + 7;

ll s[N], sv[N];
ll inv[N];

ll qpow(ll a, ll b, const ll p, ll r = 1)
{
    for (; b; b >>= 1)
        b & 1 ? r = r * a % p, a = a * a % p : a = a * a % p;
    return r;
}

int main()
{
    s[0] = 1;
    for (int i = 1; i < N; ++i)
        s[i] = s[i - 1] * i % MOD;

    sv[N - 1] = qpow(s[N - 1], MOD - 2, MOD);
    for (int i = N - 1; i >= 1; --i)
        sv[i - 1] = sv[i] * i % MOD;

    inv[0] = 1;
    for (int i = 1; i < N; ++i)
        inv[i] = sv[i] * s[i - 1] % MOD;

    int t = rr, a, b;
    while (t--)
        a = rr, b = rr, printf("%lld\n", s[a] * inv[b] % MOD * inv[a - b] % MOD);
    return 0;
}

卢卡斯定理求组合数

公式:\(\displaystyle \binom{n}{m} \bmod p = \binom{n \bmod p}{m \bmod p}\binom{n / p}{m / p} \bmod p\).

点击查看题目

网址:https://www.acwing.com/problem/content/889/

ll qpow(ll a, ll b, const ll p, ll r = 1)
{
    for (; b; b >>= 1)
        b & 1 ? r = r * a % p, a = a *a % p : a = a * a % p;
    return r;
}

ll comb(ll a, ll b, const ll p, ll r = 1)
{
    for (int i = a, j = 1; j <= b; --i, ++j)
        r = r * i % p * qpow(j, p - 2, p) % p;
    return r;
}

int lucas(ll a, ll b, const ll p, ll r = 1)
{
    while (a >= p || b >= p)
        r = r * comb(a % p, b % p, p) % p, a /= p, b /= p;
    return r * comb(a, b, p) % p;
}

int main()
{
    ll t = rr, a, b, p;
    while (t--)
        a = rr, b = rr, p = rr, printf("%lld\n", lucas(a, b, p));
    return 0;
}
点击查看题目

题目:https://www.luogu.com.cn/problem/P3807

// 这里同上...
int main()
{
    ll t = rr, a, b, p;
    while (t--)
        a = rr, b = rr, p = rr, printf("%lld\n", lucas(a + b, a, p));
    return 0;
}

Reference

[1] https://oi-wiki.org/math/number-theory/lucas/
[2] https://oi-wiki.org/math/combinatorics/combination/
[3] https://www.acwing.com/blog/content/406/文章来源地址https://www.toymoban.com/news/detail-710241.html

到了这里,关于数论——卢卡斯定理、求组合数 学习笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数论——组合数学入门

    排列就是指从给定个数的元素中取出指定个数的元素进行排序;组合则是指从给定个数的元素中仅仅取出指定个数的元素,不考虑排序。--------OI Wiki 加法原理,就好比一个工作,有 (n) 个解决的方案,第 (i) 项方案有 (a_{i}) 种不同的实现方式,所以这个工作有 (a_{1}+a_{2

    2024年02月05日
    浏览(30)
  • 蓝桥杯AcWing学习笔记 8-1数论的学习(上)

    我的AcWing 题目及图片来自蓝桥杯C++ AB组辅导课 蓝桥杯省赛中考的数论不是很多,这里讲几个蓝桥杯常考的知识点。 欧几里得算法代码: 就是因式分解的定理,所有的整数都可以唯一分解成若干个质因子乘积的形式: N = P 1 α 1 × P 2 α 2 × . . . × P k α k N=P_{1}^{α_{1}}×P_{2}^{α

    2024年01月16日
    浏览(69)
  • 数论——线性同余方程、乘法逆元 学习笔记

    众所周知: 如果爆 int 请自行开 long long 或边读边模,或高精度处理。 定义 若 (a bmod m = b bmod m) ,则称 (a) 与 (b) 关于模 (m) 同余,记为 (a equiv b pmod m) . 同余的性质 反身性: (a equiv a pmod m) ; 对称性:若 (a equiv b pmod m) ,则 (b equiv a pmod m) ; 传递性:若 (

    2024年02月08日
    浏览(33)
  • 「学习笔记」(扩展)中国剩余定理

    有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何? 该问题出自《孙子算经》,具体问题的解答口诀由明朝数学家程大位在《算法统宗》中给出: 三人同行七十希,五树梅花廿一支,七子团圆正半月,除百零五便得知。 (2 times 70 + 3 times 21 + 2 times

    2024年02月06日
    浏览(25)
  • 中国剩余定理(CRT)学习笔记

    (Aperp B) 表示 (gcd(A,B)=1) 。 (Amid B) 表示 (Bequiv 0pmod{A}(Aneq0)) 。 考虑以下这道题: 有物不知其數,三三數之剩二,五五數之剩三,七七數之剩二。 問物幾何?—— 《孫子算經》 也就是说,求出下列关于 (x) 方程组的最小整数解: [begin{cases}xequiv2pmod{3}\\\\xequiv3pmo

    2024年02月01日
    浏览(45)
  • [数论第三节]高斯消元法/求组合数/卡特兰数

    求解含有n个未知数,n个方程的多元线性方程组 O(n^3) 初等行变换: 某行乘以一个非零数 交换两行 某行加上另一行的若干倍 利用初等行变换将方程组化为上三角矩阵 解的情况: 完美阶梯型:唯一解 非完美阶梯型: 0 == 非0:无解 0 == 0:无穷解 步骤: 枚举每一列 找到这一列

    2024年02月13日
    浏览(28)
  • 算法基础学习笔记——⑬高斯消元\组合计数\容斥原理

    ✨ 博主: 命运之光 ✨ 专栏: 算法基础学习 目录 ✨高斯消元 ✨组合计数 🍓通过预处理逆元的方式求组合数: 🍓Lucas定理: 🍓分解质因数法求组合数: 前言: 算法学习笔记记录日常分享,需要的看哈O(∩_∩)O,感谢大家的支持! 高斯消元(Gaussian Elimination)是一种用于解线

    2024年02月07日
    浏览(27)
  • 最新 Vue3、TypeScript、组合式API、setup语法糖 学习笔记

    备注:目前 vue-cli 已处于维护模式,官方推荐基于 Vite 创建项目。 vite 是新一代前端构建工具,官网地址:https://vitejs.cn vite 的优势如下: 轻量快速的热重载(HMR),能实现极速的服务启动。 对 TypeScript 、 JSX 、 CSS 等支持开箱即用。 真正的按需编译,不再等待整个应用编译

    2024年02月20日
    浏览(35)
  • 机器学习中高维组合特征的处理方法+推荐系统使用矩阵分解为用户推荐的原理解析,《百面机器学习》学习笔记

    为了提高复杂关系的拟合能力,在特征工程中经常会把一阶离散特征进行组合,构成高阶组合特征。 假设有A B两组特征,C为受到A B两种特征影响的因素,且对特征A来说,其有 A i , i ∈ [ 0 , 1 ] {A^i,iin [0,1]} A i , i ∈ [ 0 , 1 ] 两种特征取值。同时,对于特征B来说,其有 B j , j ∈

    2024年02月05日
    浏览(33)
  • 【设计模式——学习笔记】23种设计模式——组合模式Composite(原理讲解+应用场景介绍+案例介绍+Java代码实现)

    编写程序展示一个学校院系结构: 需求是这样,要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系 【传统方式】 将学院看做是学校的子类,系是学院的子类,小的组织继承大的组织 分析: 在一个页面中展示出学校的院系组成,一个学校有多个

    2024年02月15日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包