C++ 把一个数字提高到一个大指数

C++ 把一个数字提高到一个大指数,c++,arrays,algorithm,math,integer-arithmetic,C++,Arrays,Algorithm,Math,Integer Arithmetic,我得到了数字3和一个变量“n”,可以高达10亿。我必须打印3^n模100003的答案。我尝试了以下方法: 我尝试使用函数std::pow3,n,但它对大指数不起作用。在此过程中,请不要应用模。 我尝试实现我自己的函数,将数字3提高到n的幂,以便在需要时应用模,但是当使用非常大的数字进行测试时,这种方法被证明太慢。 最后,我尝试了对数字“n”的素数分解,然后使用“n”的因子以及它们出现的次数来构建答案,如果它是正确的,这似乎是我能想到的最好的方法。问题是,对于一个已经是素数的巨大数字,我该怎么办

我得到了数字3和一个变量“n”,可以高达10亿。我必须打印3^n模100003的答案。我尝试了以下方法:

我尝试使用函数std::pow3,n,但它对大指数不起作用。在此过程中,请不要应用模。 我尝试实现我自己的函数,将数字3提高到n的幂,以便在需要时应用模,但是当使用非常大的数字进行测试时,这种方法被证明太慢。 最后,我尝试了对数字“n”的素数分解,然后使用“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);
}

利用模运算的特性

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

这是为了补充Kaidul的答案

100003是一个素数,它立即转换为:任何提升到素数幂的数都与其自身与该素数的模同余。这意味着你不需要提升到n级。n%100002功率就足够了

编辑:示例

比如说,n是200008,也就是100002*2+6。现在,

FLT声称3^100002%100003==1,上面的最后一行,模100003,减少到3^6。一般来说,对于素数p


当然,只有当指数n大于p时,它才会加快计算速度。根据您的要求,指数100,模100003,无需减少。直接转到Kaidul的方法。

这是为了补充Kaidul的答案

100003是一个素数,它立即转换为:任何提升到素数幂的数都与其自身与该素数的模同余。这意味着你不需要提升到n级。n%100002功率就足够了

编辑:示例

比如说,n是200008,也就是100002*2+6。现在,

FLT声称3^100002%100003==1,上面的最后一行,模100003,减少到3^6。一般来说,对于素数p


当然,只有当指数n大于p时,它才会加快计算速度。根据您的要求,指数100,模100003,无需减少。直接转到Kaidul的方法。

。@Kaidul非常感谢。@Kaidul非常感谢。我似乎不知道如何准确地使用这个定理。你能解决一个例子,让我更清楚吗?例如,假设我们有基数3,指数100和模100003。结果是60258,那么我如何使用这个定理来得到正确的答案呢?明白了。谢谢我似乎不明白如何确切地使用这个定理。你能解决一个例子,让我更清楚吗?例如,假设我们有基数3,指数100和模100003。结果是60258,那么我如何使用这个定理来得到正确的答案呢?明白了。谢谢