【问题标题】:calculating modulo of a^n faster than o(n) [duplicate]比 o(n) 更快地计算 a^n 的模
【发布时间】:2019-05-25 16:06:16
【问题描述】:

我需要计算(a^n) mod b。我使用了这个 java 代码,但是当n 太大时它不够快。

for (long i = 0; i < n; i++) {
    ans = (ans * a) % b;
}

正如你在上面的代码中看到的,n 是一个long 数字,所以这个算法不够快。你有什么更快的算法吗? 可能看起来像这个问题,但有点不同:Fast way to calculate n! mod m where m is prime?

【问题讨论】:

  • 平方取幂

标签: java c++ algorithm data-structures


【解决方案1】:

利用模运算的性质

(x × y) modulo b == ((x modulo b) × (y modulo b)) modulo b

使用上面的乘法规则

(a^n) modulo b
= (a × a × a × a ... × a) modulo b 
= ((a modulo b) × (a modulo b) × (a modulo b) ... × (a modulo b)) modulo b

通过分而治之的方法计算结果。递归关系将是:

f(x, n) = 0                     if n == 0

f(x, n) = (f(x, n / 2))^2       if n is even
f(x, n) = (f(x, n / 2))^2 * x   if n is odd

这里是 C++ 实现:

int powerUtil(int base, int exp, int mod) {
    if(exp == 0) return 1;
    int ret = powerUtil(base, exp / 2, mod) % mod;
    ret = 1LL * ret * ret % mod;
    if(exp & 1) {
        ret = 1LL * ret * base % mod;
    }
    return ret;
}

double power(int base, int exp, int mod) {
    if(exp < 0) {
        if(base == 0) return DBL_MAX; // undefined
        return 1 / (double) powerUtil(base, -exp, mod);
    }
    return powerUtil(base, exp, mod);
}

时间复杂度为O(logn)

Here is my original answer。希望对您有所帮助!

【讨论】:

  • 因为结果是mod,而你想要精度,我会使用long(或long long)而不是double
  • @Kaidul 谢谢。成功了!
【解决方案2】:

您可以使用线程来划分 n。然后当你finalize为mul时,你可以mul最后的结果,然后制作mod。

例如:

n=4 然后分开 2 个线程,每个线程将如下:

int ans=1;
for(int i =0; i<n_thread;i++){
   ans = ans*a;
}

最后,当线程完成时,您必须计算结果,然后制作 b 的 mod。 我不会告诉你如何使用线程,因为你必须自己学习,但是如果你在搜索和了解线程后对线程有疑问,那么你可以寻求帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-25
    • 1970-01-01
    • 2023-03-25
    • 2011-06-25
    • 2021-12-22
    • 1970-01-01
    • 2014-11-04
    • 2018-12-30
    相关资源
    最近更新 更多