【问题标题】:Big mod algorithm for range 10^18? [closed]范围 10^18 的大模算法? [关闭]
【发布时间】:2015-09-21 18:43:58
【问题描述】:

我必须计算 N^X MOD 10^18+7 并且我的范围是 1

【问题讨论】:

  • 为您选择的语言使用大量库。由于您没有指定您的语言或更多详细信息,因此这个问题可能会因为过于宽泛而很快结束。在此之前编辑并添加额外信息:)
  • “通常的 big mod 算法将无法计算这个”。是什么让你这么说?我认为它会工作得很好。
  • 范围是 10^18 。 10^18+7 的最小模数是多少? 10^18 。如果我的两个输入都是 10^18 那么它会导致溢出。
  • @Kevin 不,不会。要计算 n^x%m,你必须做很多 n*n。如果 m>n>sqrt(2^63-1) 这将溢出
  • 再次,什么语言?浮点数/双精度数可能适用于您(取决于准确性),或其他擅长制作更大数据类型的系统。 “溢出”不是算法或数论的事情。这是语言问题。

标签: c++ algorithm number-theory


【解决方案1】:

有一个不涉及使用 bignums 的解决方案。简单解决方案的主要问题是需要计算n*n。如果n>sqrt(2^63-1) 将溢出int64 数字。解决这个问题的方法是像计算 n^x%m 一样计算 n*n%m

我的意思是,你必须实现一个自定义的模乘法,通过只做加法来避免溢出。

在 C++ 中,这将类似于:

#include <iostream>
using namespace std;

template <typename T>
T mmul(T a, T b, T m) {
    a %= m;
    T result = 0;
    while (b) {
        if (b % 2) result = (result + a) % m;
        a = (a + a) % m;
        b /= 2;
    }
    return result;
}

template <typename T>
T mpow(T a, T b, T m) {
    a %= m;
    T result = 1;
    while (b) {
        if (b % 2) result = mmul(result, a, m);
        a = mmul(a, a, m);
        b /= 2;
    }
    return result;
}


int main() {
    long long big = 1000000000000000000;
    cout << mpow(big+1, big+2, big+7) << endl;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多