Raising a number to a huge exponent

前端 未结 2 801
野的像风
野的像风 2021-01-23 20:17

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 followi

相关标签:
2条回答
  • 2021-01-23 20:59

    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.

    0 讨论(0)
  • 2021-01-23 21:15

    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);
    }
    
    0 讨论(0)
提交回复
热议问题