Raising a number to a huge exponent

允我心安 提交于 2019-12-02 11:21:11

问题


I am given the number 3 and a variable 'n', that can be as high as 1 000 000 000 (a billion). I have to print the answer of 3^n modulo 100003. I tried the following:

  1. I tried using the function std::pow(3,n), but it doesn't work for large exponents(can't apply the modulo during the process).
  2. I tried implementing my own function that would raise the number 3 to the power n so I could apply the modulo when needed, but when tested with very large numbers, this method proved to be too slow.
  3. Lastly I tried prime factorization of the number 'n' and then using the factors of 'n' (and how many times they appear) to build back the answer and this seems like the best method that I could come up with (if it is correct). The problem is what would I do for a huge number that is already prime?

    So these were the ideas that I had, if anyone thinks there's a better way (or if one of my methods is optimal), I would appreciate any guidance.


回答1:


Take advantage of property of modular arithmetic

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

By using above multiplication rule

(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

Calculate the result by divide and conquer approach. The recurrence relation will be:

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

Here is the C++ implementation:

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



回答2:


This is to augment Kaidul's answer.

100003 is a prime number, which immediately casts in the Fermat's Little Theorem: any number raised to a prime power is congruent to itself modulo that prime. It means that you don't need to raise to n'th power. A n % 100002 power suffices.

Edit: example.

Say, n is 200008, which is 100002 * 2 + 6. Now,

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

FLT claims that (3 ^ 100002) % 100003 == 1, and the last line above, modulo 100003, reduces to 3 ^ 6. In general, for a prime p,

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

Of course, it only speeds the computation if the exponent n is greater than p. As per your request (exponent 100, modulo 100003) there is nothing to reduce. Go straight to the Kaidul's approach.



来源:https://stackoverflow.com/questions/52283446/raising-a-number-to-a-huge-exponent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!