将数字提高到一个巨大的指数

Raising a number to a huge exponent

本文关键字:一个 巨大 指数 数字      更新时间:2023-10-16

我得到数字3和一个变量'n',可以高达1 000 000 000(十亿(。我必须打印3^n modulo 100003的答案.我尝试了以下方法:

  1. 我尝试使用函数std::pow(3,n),但它不适用于大指数(在此过程中无法应用模数(。
  2. 尝试实现我自己的函数,将数字 3 提高到 n 的幂,以便我可以在需要时应用模数,但是当用非常大的数字进行测试时,这种方法被证明太慢了。
  3. 最后,我尝试了数字"n"的
  4. 质因式分解,然后使用"n"的因数(以及它们出现的次数(来构建答案,这似乎是我能想到的最好的方法(如果它是正确的(。问题是,对于已经是素数的大量数字,我会怎么做?

    所以这些是我的想法,如果有人认为有更好的方法(或者如果我的方法之一是最佳的(,我将不胜感激任何指导。

利用模算术的属性

(a × b) modulo M == ((a module M) × (b modulo M)) modulo M

通过使用上述乘法规则

(a^n) modulo M 
= (a × a × a × a ... × a) modulo M 
= ((a module M) × (a modulo M) × (a modulo M) ... × (a modulo M)) modulo M

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

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);
}

这是为了补充凯杜尔的答案。

100003是一个素数,它立即投射到费马小定理:任何提高到素幂的数都与该素数的自身模全等。这意味着你不需要提高到n的幂。n % 100002的力量就足够了。

编辑:示例。

比如说,n是200008,这是100002 * 2 + 6.现在

3 ^ 200007 =
3 ^ (100002 + 100002 + 6) = 
3 ^ 100002 * 3 ^ 100002 * 3 ^ 6

FLT声称(3 ^ 100002) % 100003 == 1,以及上面的最后一行,模100003,简化为3 ^ 6。一般来说,对于一个素数p

(k ^ n) % p == k ^ (n % p)

当然,它只有在指数n大于p时才加快计算速度。根据您的要求(指数100,模100003(,没有什么可以减少的。直接进入凯杜尔的方法。