Open In App

Fibonacci Power

Last Updated : 30 May, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given a number n. You are required to find ( Fib(n) ^ Fib(n) ) % 10^9 + 7, where Fib(n) is the nth fibonacci number.

Examples : 

Input : n = 4 
Output : 27 
4th fibonacci number is 3 
[ fib(4) ^ fib(4) ] % 10^9 + 7 = ( 3 ^ 3 ) % 10^9 + 7 = 27 

Input : n = 3 
Output : 4 
3th fibonacci number is 2 
[ fib(3) ^ fib(3) ] % 10^9 + 7 = ( 2 ^ 2 ) % 10^9 + 7 = 4 

If n is large, fib(n) will be huge and fib(n) ^ fib(n) is not only difficult to calculate but its storage is impossible.

Approach: 
( a ^ (p-1) ) % p = 1 where p is prime number (using Fermat Little Theorem). 
( a ^ a ) % m can be written as ( ( a % m ) ^ a ) % m 
It is also possible to write any number ‘a’ as a = k * ( m – 1 ) + r (Using Division Algorithm) 
where ‘k’ is quotient and ‘r’ is remainder. We can say that r = a % (m-1) 
So, Steps to reduce our calculation, lets suppose a = fib(n) 

  ( a ^ a ) % m 
= ( ( a % m ) ^ a ) % m 
= ( ( a % m ) ^ ( k * ( m - 1 ) + r ) ) % m 
= ( ( ( a % m ) ^ ( m-1 ) ) ^ k  * ( a % m ) ^ r ) % m
= ( (1 ^ k) * ( a % m ) ^ r ) % m
= ( ( a % m ) ^ r ) % m   
= ( ( a % m ) ^ (a % (m-1) ) % m 

a % m and a % (m-1) are easy to calculate and easy to store. 
and we can calculate ( x ^ y ) % m using this GFG article. 
We can find nth fibonacci number in log(n) time using this GFG article.

Below is the implementation of above approach :  

C++




#include <bits/stdc++.h>
#define mod 1000000007
using namespace std;
  
// Iterative function to compute modular power
long long modularexpo(long long x, long long y, long long p)
{
    // Initialize result
    long long res = 1;
    // Update x if it is more than or
    // equal to p
    x = x % p;
  
    while (y > 0) {
        // If y is odd, multiply x with result
        if (y & 1)
            res = (res * x) % p;
  
        // y must be even now
        y = y >> 1;
        x = (x * x) % p;
    }
    return res;
}
 
// Helper function that multiplies 2 matrices
// F and M of size 2*2, and puts the
// multiplication result back to F[][]
void multiply(long long F[2][2], long long M[2][2], long long m)
{
    long long x = ((F[0][0] * M[0][0]) % m +
                   (F[0][1] * M[1][0]) % m) % m;
 
    long long y = ((F[0][0] * M[0][1]) % m +
                   (F[0][1] * M[1][1]) % m) % m;
 
    long long z = ((F[1][0] * M[0][0]) % m +
                   (F[1][1] * M[1][0]) % m) % m;
 
    long long w = ((F[1][0] * M[0][1]) % m +
                   (F[1][1] * M[1][1]) % m) % m;
  
    F[0][0] = x;
    F[0][1] = y;
    F[1][0] = z;
    F[1][1] = w;
}
 
// Helper function that calculates F[][] raise to
// the power n and puts the  result in F[][]
// Note that this function is designed only for fib()
// and won't work as general power function
void power(long long F[2][2], long long n, long long m)
{
    if (n == 0 || n == 1)
        return;
    long long M[2][2] = { { 1, 1 }, { 1, 0 } };
  
    power(F, n / 2, m);
    multiply(F, F, m);
  
    if (n % 2 != 0)
        multiply(F, M, m);
}
 
// Function that returns nth Fibonacci number
long long fib(long long n, long long m)
{
    long long F[2][2] = { { 1, 1 }, { 1, 0 } };
    if (n == 0)
        return 0;
    power(F, n - 1, m);
    return F[0][0];
}
 
// Driver Code
int main()
{
    long long n = 4;
    long long base = fib(n, mod) % mod;
    long long expo = fib(n, mod - 1) % (mod - 1);
    long long result = modularexpo(base, expo, mod) % mod;
    cout << result << endl;
}


Java




class GFG
{
static int mod = 1000000007;
 
// Iterative function to compute modular power
static long modularexpo(long x, long y, long p)
{
    // Initialize result
    long res = 1;
     
    // Update x if it is more than or
    // equal to p
    x = x % p;
 
    while (y > 0)
    {
        // If y is odd, multiply x with result
        if (y % 2 == 1)
            res = (res * x) % p;
 
        // y must be even now
        y = y >> 1;
        x = (x * x) % p;
    }
    return res;
}
 
// Helper function that multiplies 2 matrices
// F and M of size 2*2, and puts the
// multiplication result back to F[][]
static void multiply(long F[][],
                     long M[][], long m)
{
    long x = ((F[0][0] * M[0][0]) % m +
              (F[0][1] * M[1][0]) % m) % m;
 
    long y = ((F[0][0] * M[0][1]) % m +
              (F[0][1] * M[1][1]) % m) % m;
 
    long z = ((F[1][0] * M[0][0]) % m +
              (F[1][1] * M[1][0]) % m) % m;
 
    long w = ((F[1][0] * M[0][1]) % m +
              (F[1][1] * M[1][1]) % m) % m;
 
    F[0][0] = x;
    F[0][1] = y;
    F[1][0] = z;
    F[1][1] = w;
}
 
// Helper function that calculates F[][] raise to
// the power n and puts the result in F[][]
// Note that this function is designed only for fib()
// and won't work as general power function
static void power(long F[][], long n, long m)
{
    if (n == 0 || n == 1)
        return;
    long M[][] = { { 1, 1 }, { 1, 0 } };
 
    power(F, n / 2, m);
    multiply(F, F, m);
 
    if (n % 2 != 0)
        multiply(F, M, m);
}
 
// Function that returns nth Fibonacci number
static long fib(long n, long m)
{
    long F[][] = { { 1, 1 }, { 1, 0 } };
    if (n == 0)
        return 0;
    power(F, n - 1, m);
    return F[0][0];
}
 
// Driver Code
public static void main(String[] args)
{
    long n = 4;
    long base = fib(n, mod) % mod;
    long expo = fib(n, mod - 1) % (mod - 1);
    long result = modularexpo(base, expo, mod) % mod;
    System.out.println(result);
}
}
 
// This code is contributed by PrinciRaj1992


Python3




mod = 1000000007;
 
# Iterative function to compute modular power
def modularexpo(x, y, p):
 
    # Initialize result
    res = 1;
     
    # Update x if it is more than or
    # equal to p
    x = x % p;
 
    while (y > 0):
         
        # If y is odd, multiply x with result
        if (y & 1):
            res = (res * x) % p;
 
        # y must be even now
        y = y >> 1;
        x = (x * x) % p;
     
    return res;
 
# Helper function that multiplies 2 matrices
# F and M of size 2*2, and puts the
# multiplication result back to F[][]
def multiply(F, M, m):
 
    x = ((F[0][0] * M[0][0]) % m +
         (F[0][1] * M[1][0]) % m) % m;
 
    y = ((F[0][0] * M[0][1]) % m +
         (F[0][1] * M[1][1]) % m) % m;
 
    z = ((F[1][0] * M[0][0]) % m +
         (F[1][1] * M[1][0]) % m) % m;
 
    w = ((F[1][0] * M[0][1]) % m +
         (F[1][1] * M[1][1]) % m) % m;
 
    F[0][0] = x;
    F[0][1] = y;
    F[1][0] = z;
    F[1][1] = w;
 
# Helper function that calculates F[][] raise to
# the power n and puts the result in F[][]
# Note that this function is designed only for fib()
# and won't work as general power function
def power(F, n, m):
 
    if (n == 0 or n == 1):
        return;
    M = [[ 1, 1 ], [ 1, 0 ]];
 
    power(F, n // 2, m);
    multiply(F, F, m);
 
    if (n % 2 != 0):
        multiply(F, M, m);
 
# Function that returns nth Fibonacci number
def fib(n, m):
 
    F = [[ 1, 1 ], [ 1, 0 ]];
    if (n == 0):
        return 0;
    power(F, n - 1, m);
    return F[0][0];
 
# Driver Code
if __name__ == '__main__':
    n = 4;
    base = fib(n, mod) % mod;
    expo = fib(n, mod - 1) % (mod - 1);
    result = modularexpo(base, expo, mod) % mod;
    print(result);
 
# This code is contributed by 29AjayKumar


C#




using System;
 
class GFG
{
static int mod = 1000000007;
 
// Iterative function to compute modular power
static long modularexpo(long x, long y, long p)
{
    // Initialize result
    long res = 1;
     
    // Update x if it is more than or
    // equal to p
    x = x % p;
 
    while (y > 0)
    {
        // If y is odd, multiply x with result
        if (y % 2 == 1)
            res = (res * x) % p;
 
        // y must be even now
        y = y >> 1;
        x = (x * x) % p;
    }
    return res;
}
 
// Helper function that multiplies 2 matrices
// F and M of size 2*2, and puts the
// multiplication result back to F[,]
static void multiply(long [,]F,
                     long [,]M, long m)
{
    long x = ((F[0, 0] * M[0, 0]) % m +
              (F[0, 1] * M[1, 0]) % m) % m;
 
    long y = ((F[0, 0] * M[0, 1]) % m +
              (F[0, 1] * M[1, 1]) % m) % m;
 
    long z = ((F[1, 0] * M[0, 0]) % m +
              (F[1, 1] * M[1, 0]) % m) % m;
 
    long w = ((F[1, 0] * M[0, 1]) % m +
              (F[1, 1] * M[1, 1]) % m) % m;
 
    F[0, 0] = x;
    F[0, 1] = y;
    F[1, 0] = z;
    F[1, 1] = w;
}
 
// Helper function that calculates F[,] raise to
// the power n and puts the result in F[,]
// Note that this function is designed only for fib()
// and won't work as general power function
static void power(long [,]F, long n, long m)
{
    if (n == 0 || n == 1)
        return;
    long [,]M = { { 1, 1 }, { 1, 0 } };
 
    power(F, n / 2, m);
    multiply(F, F, m);
 
    if (n % 2 != 0)
        multiply(F, M, m);
}
 
// Function that returns nth Fibonacci number
static long fib(long n, long m)
{
    long [,]F = { { 1, 1 }, { 1, 0 } };
    if (n == 0)
        return 0;
    power(F, n - 1, m);
    return F[0, 0];
}
 
// Driver Code
public static void Main(String[] args)
{
    long n = 4;
    long Base = fib(n, mod) % mod;
    long expo = fib(n, mod - 1) % (mod - 1);
    long result = modularexpo(Base, expo, mod) % mod;
    Console.WriteLine(result);
}
}
 
// This code is contributed by Rajput-Ji


Javascript




<script>
 
let mod = 1000000007;
 
// Iterative function to compute modular power
function modularexpo(x, y, p)
{
     
    // Initialize result
    let res = 1;
     
    // Update x if it is more than or
    // equal to p
    x = x % p;
 
    while (y > 0)
    {
         
        // If y is odd, multiply x with result
        if (y % 2 == 1)
            res = (res * x) % p;
 
        // y must be even now
        y = y >> 1;
        x = (x * x) % p;
    }
    return res;
}
 
// Helper function that multiplies 2 matrices
// F and M of size 2*2, and puts the
// multiplication result back to F[][]
function multiply(F, M, m)
{
    let x = ((F[0][0] * M[0][0]) % m +
             (F[0][1] * M[1][0]) % m) % m;
 
    let y = ((F[0][0] * M[0][1]) % m +
             (F[0][1] * M[1][1]) % m) % m;
 
    let z = ((F[1][0] * M[0][0]) % m +
             (F[1][1] * M[1][0]) % m) % m;
 
    let w = ((F[1][0] * M[0][1]) % m +
             (F[1][1] * M[1][1]) % m) % m;
 
    F[0][0] = x;
    F[0][1] = y;
    F[1][0] = z;
    F[1][1] = w;
}
 
// Helper function that calculates F[][] raise to
// the power n and puts the result in F[][]
// Note that this function is designed only for fib()
// and won't work as general power function
function power(F, n, m)
{
    if (n == 0 || n == 1)
        return;
         
    let M = [ [ 1, 1 ], [ 1, 0 ] ];
     
    power(F, Math.floor(n / 2), m);
    multiply(F, F, m);
 
    if (n % 2 != 0)
        multiply(F, M, m);
}
 
// Function that returns nth Fibonacci number
function fib(n, m)
{
    let F = [ [ 1, 1 ], [ 1, 0 ] ];
    if (n == 0)
        return 0;
         
    power(F, n - 1, m);
    return F[0][0];
}
 
// Driver Code
let n = 4;
let base = fib(n, mod) % mod;
let expo = fib(n, mod - 1) % (mod - 1);
let result = modularexpo(base, expo, mod) % mod;
 
document.write(result);
 
// This code is contributed by code_hunt
 
</script>


Output: 

27

 

Time Complexity: log(n)

Auxiliary Space: O(1)
 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads