0

Problem link-http://www.spoj.com/problems/LASTDIG/

Summary-Given 2 non negative integers a and b, print the last digit of a^b.

I tried using an algorithm to find the modular exponentiation using less memory space(http://en.wikipedia.org/wiki/Modular_exponentiation#Memory-efficient_method) but I am getting a TLE(Time Limit Exceeding) error for my solution. What changes should I make to run my code in within 1 second? Note that 10 test cases need to run within 1 second.

My solution:

#include<iostream>
#include<vector>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>

typedef long long LL;

using namespace std;


int ME(LL A, LL B)
{
    LL c=1;
    int E=0;

    while(E<B)
    {
        c=(c*A)%10;
        E++;
    }

    return c;
}

int main()
{
    int t;
    LL a, b;
    vector <int> lDigit(31);

    cin>>t;
    for(int i=0;i<t;i++)
    {
        cin>>a>>b;

        if(b>=99999)
            lDigit[i]=ME(a, b);
        else
        {
            int temp=pow(a, b);
            lDigit[i]=temp%10;
        }
    }

    for(int i=0;i<t;i++)
        cout<<lDigit[i]<<endl;

    return 0;
}
vishal_khanna
  • 57
  • 1
  • 9
  • i don't know whether this will get your answer accepted but generally use scanf,printf instead of cin/cout – abkds Aug 18 '14 at 09:17
  • 1
    http://codereview.stackexchange.com/ should be a better site for this question. – mch Aug 18 '14 at 09:22

1 Answers1

1

The algorithm that you are using will be slow for large exponentiations. The fast modular exponentiation considers the bits in the exponent, and needs only O(lg(n)) multiplications/divisions whereas your code needs O(n) multiplications. At exponent of 1 billion the difference is about 1 billion to ~30. See the Right-to-left binary method.

The pseudocode from Wikipedia is

function modular_pow(base, exponent, modulus)
    Assert :: (modulus - 1) * (base mod modulus) does not overflow base
    result := 1
    base := base mod modulus
    while exponent > 0
        if (exponent mod 2 == 1):
           result := (result * base) mod modulus
        exponent := exponent >> 1
        base := (base * base) mod modulus
    return result

Which in C becomes

int modular_pow(int base, int exponent, int modulus) {
    int result = 1;
    base = base % modulus;
    while (exponent) {
        if (exponent & 1) {
            result = (result * base) % modulus;
        }
        exponent >>= 1;
        base = base * base % modulus;
    }
    return result;
}

Whereas your code runs the while loop 2 billion times for exponents of 2 billion, the code above runs the loop ~32 times.