【问题标题】:Modular Exponentiation (Power in Modular Arithmetic) [closed]模幂(模算术中的幂)[关闭]
【发布时间】:2018-01-15 21:36:11
【问题描述】:

你好!
我一直在理解模幂的概念。当我需要这个以及它是如何工作的。
假设我将幂函数称为:power(2,n-1)。
n=10 的循环将如何执行,以及以下问题的时间和空间复杂度

#define m 1000000007

unsigned long long int power(unsigned long long int x, unsigned long long int n){

    unsigned long long int res = 1;
    while(n > 0){
        if(n & 1){
            res = res * x;
            res = res % m;
        }
        x = x * x;
        x= x % m;
        n >>= 1;
    }
    return res;

}

【问题讨论】:

  • 您的问题“循环将如何执行,例如 n=10”尚不清楚。你不能把这些步骤写在纸上或者使用调试器看看在这种特殊情况下会发生什么吗?在任何情况下,您的 x 和 n 值都太小,无法通过 m 进行模数运算,因此这不是最好的例子案子。您的意思是要问一般来说,该功能是如何以及为什么起作用的?
  • 是的@RoryDaulton。这个函数是如何工作的?
  • 搜索“平方求幂”,这将解释除% m 行之外的所有内容,这些行用于使所有内容都以m 为模。如果这些解释中有什么你不明白的,那么回来询问更多细节。
  • 注意:(a * b) mod m == ((a mod m) * (b mod m)) mod m 这个关系可以用来保持中间值在范围内。跨度>

标签: c++ c algorithm math


【解决方案1】:

从 DAle 链接的 Wikipedia 页面上的模数定律(关于您之前的问题),我们可以获得两个公式:

从第一个公式可以看出,我们可以从n / 2 的结果中迭代计算n 的模数。这是通过行来完成的

x = x * x;
x = x % m;

因此算法中有log n 步骤,因为每次x 的指数翻倍。计步由n >>= 1 和while (n > 0) 完成,计步为log n。

现在,您可能想知道 1)为什么这部分不设置 res 的值,以及 2)这些行的目的是什么

if(n & 1){
   res = res * x;
   res = res % m;
}

这是必要的,因为在迭代的某些点,无论是开始还是结束,n 的值可能是奇数。我们不能忽略它并继续使用公式 1,因为这意味着我们将跳过x 的幂! (整数除法向下舍入,例如5 >> 1 = 2,我们将使用x^4 而不是x^5)。此 if 语句处理 n 为奇数时的情况,即 n % 2 = n & 1 = 1。它只是使用上面的公式 2 将x 的单个幂“添加”到结果中。

【讨论】:

    猜你喜欢
    • 2014-08-21
    • 2020-09-11
    • 2017-02-02
    • 2014-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-19
    相关资源
    最近更新 更多