Compute nCr%p Using Fermat Little Theorem in Java2025年5月7日 | 阅读7分钟 使用费马小定理可以有效地处理计算组合数模素数 p 的任务。组合公式 nCr 表示从 n 个元素的集合中选择 r 个元素的总方法数。费马小定理提供了一种计算模逆的有效方法,从而简化了该过程。 组合公式为 nCr = n! / (r!(n - r)!) 它表示从 n 个元素的集合中选择 r 个元素的数量,其中
示例 1 输入:n = 10, r = 2, p = 13 输出 6 解释 10C2 = 10! / (2! * (10 - 2)!) = 10 * 9 / (2 * 1) = 45 45 % 13 = 6 示例 2 输入:n = 6, r = 2, p = 13 输出 2 解释 6C2 = 6! / (2! * (6 - 2)!) = 6 * 5 / (2 * 1) = 15 15 % 13 = 2 费马小定理与模逆费马小定理指出,如果 p 是一个素数,那么对于任何整数 a,a^p - a 的值都可以被 p 整除。使用模运算,这可以表示为 ap = a (mod p) 例如,如果 a = 2 且 p = 7,则 27 = 128,并且 128 - 2 = 7 × 18 是 7 的整数倍。 如果 a 不能被 p 整除,费马小定理指出 a^(p-1) - 1 可以被 p 整除。在模运算中,这写为 ap-1 = 1 (mod p) 如果我们用 a-1 乘以两边,则得到。 ap-2 = a-1 (mod p) 因此,我们可以将模逆找到为 p-2。 使用模运算预先计算阶乘这种方法涉及预先计算所有小于等于 n 的值的模 p 的阶乘,这允许高效地计算组合数。通过存储阶乘值并使用费马小定理进行模逆计算,我们可以在预先计算后以常数时间计算 nCr mod p。 算法步骤 1:检查 n<r:如果为真,则返回 0(因为从 n 个元素中选择 r 个是不可能的)。 步骤 2:检查 r=0:如果为真,则返回 1(因为 nC0=1)。 步骤 3:计算模 p 的阶乘:初始化一个阶乘数组 factorial[] 来存储从 1! 到 n! 的模 p 的阶乘值。 步骤 4:计算模逆:使用费马小定理,使用公式 a^(p-2) mod p 计算 factorial[r] 和 factorial[n-r] 的模逆。 步骤 5:应用组合公式:将 nCr mod p 计算为 nCr % p = (factorials[n] * inverseMod(factorials[r], p) * inverseMod(factorials[n - r], p)) % p 步骤 6:返回结果:打印 nCr mod p 的结果。 实施文件名:CombinationModulo.java 输出 The value of 10C2 modulo 13 is: 6 时间复杂度:O(n+log(mod))。 辅助空间复杂度:O(n)。 我们可以通过消除存储阶乘的单独数组的需要来优化空间复杂度。取而代之的是,我们可以在应用约简时直接乘以数字。 算法步骤 1:通过重复平方基数和减半指数来高效地计算 base^exp % mod。 步骤 2:使用费马小定理查找 number^-1 % mod,即 number^(mod-2) % mod。 步骤 3:将两个数字模 mod 相乘,或通过计算分母的模逆来除。 步骤 4:计算 nCr:
步骤 5:调用函数计算 nCr % mod 并打印结果。 实施文件名:CombinationCalculator.java 输出 Result of nCr % p is: 6 时间复杂度:O(r⋅log(mod)) 辅助空间复杂度: O(1) 下一主题什么是面向对象编程? |
在 Java 中,Future 和 Callable 接口是 java.util.concurrent 包的重要组成部分。它们提供了一种机制来管理异步任务的结果并处理异步任务。尽管它们都有类似的功能,但它们之间存在一些显著的差异,这些差异是...
阅读 3 分钟
Java 中的 BreakIterator ious() 方法及示例 java.text.BreakIterator 类包含一个 ious() 方法。通过调用 current() 方法可以获得当前边界,而使用 BreakIterator 类可以获得其后面 ious 边界的索引。它给出了第一个...的偏移量。
阅读 3 分钟
在本教程中,我们将了解如何在 Java 中多次执行 main() 方法。方法:使用静态块我们知道静态块首先执行。因此,它可以用来显式执行 main 方法。一个被隐式执行为主...
阅读 2 分钟
Java EE v/s Node.js Java EE 代表 Java Enterprise Edition,目前称为 Jakarta EE。在过去的十年中,它被称为 J2EE。Java EE 为 Java 开发人员提供了企业级功能(如 Web 服务和分布式计算)的平台。在……
阅读 2 分钟
在给定的整数数组 arr[](大小为 n)中,找到仅由素数组成的连续子数组的最大和。换句话说,不允许在选定的子数组中存在非素数。示例 1:输入:int a[] = {...
7 分钟阅读
覆盖距离的可能方式计数问题可以表述为“楼梯”问题的简单推广,唯一的区别是人一次最多可以迈三步来覆盖给定的距离。这简化了后勤...
阅读 8 分钟
我们可以通过 reverse()、split()、toLowerCase()、toUpperCase() 和 substring() 方法来反转字符串中每个单词的大小写。通过 split("\\s") 方法,我们可以将所有单词获取到一个数组中。要获取第一个字符,我们可以使用 substring() 或 charAt()...
阅读1分钟
具有相同数字集合的更大数字(Java)给出了一个数字 (num)。任务是找到一个由 num 的相同数字组成且大于 num 的最小数字。如果数字 num...
阅读 8 分钟
Sets.union() 方法在 Java 中返回两个集合的并集的不可变表示。存在于任一备份集合中的每个元素都包含在返回的集合中。在迭代所有返回的集合时,set2 的每个成员(如果不存在...)
阅读 3 分钟
在本节中,我们将讨论如何在 Java 中将矩阵旋转 180 度。在这个问题中,给出了一个方形矩阵,我们需要将其旋转 1800 度。示例 1:输入:4 6 7 8 9 3 2 1 9 0 4 5 8 0 3 2 输出:2 3...
阅读 10 分钟
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India