// Arup Guha
// 10/23/2020
// Fast Mod Expo Code Written in Class

#include <stdio.h>
#include <time.h>

long long fastmodexpo(long long base, long long exp, long long mod);
long long slowmodexpo(long long base, long long exp, long long mod);

int main(void) {

    // Run fast mod expo and time it.
    int s = time(0);
    printf("%lld\n", fastmodexpo(123456789ll, 1000000000ll, 1000000007ll));
    int e = time(0);
    printf("Fast took %d time\n", e-s);

    // Do the same for the repeated multiplication method.
    printf("%lld\n", slowmodexpo(123456789ll, 1000000000ll, 1000000007ll));
    int e2 = time(0);
    printf("slow took %d\n", e2-e);
    return 0;
}

// Returns base to the power exp mod mod.
long long fastmodexpo(long long base, long long exp, long long mod) {

    // No more multiplicat.
    if (exp == 0) return 1ll%mod;

    // Even, so go to the square root and square it.
    if (exp%2 == 0) {
        long long temp = fastmodexpo(base, exp/2, mod);
        return (temp*temp)%mod;
    }

    // Regular multiply by base case.
    return (fastmodexpo(base,exp-1,mod)*base)%mod;
}

// Regular algorithm to calculate base to the exp mod mod.
long long slowmodexpo(long long base, long long exp, long long mod) {
    long long ans = 1;
    for (int i=0; i<exp; i++)
        ans = (ans*base)%mod;
    return ans;
}
