Related Articles

# Fibonacci Power

• Difficulty Level : Hard
• Last Updated : 07 Jun, 2021

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 ``#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, ``long` `long` `M, ``long` `long` `m)``{``    ``long` `long` `x = ((F * M) % m +``                   ``(F * M) % m) % m;` `    ``long` `long` `y = ((F * M) % m +``                   ``(F * M) % m) % m;` `    ``long` `long` `z = ((F * M) % m +``                   ``(F * M) % m) % m;` `    ``long` `long` `w = ((F * M) % m +``                   ``(F * M) % m) % m;`` ` `    ``F = x;``    ``F = y;``    ``F = z;``    ``F = 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, ``long` `long` `n, ``long` `long` `m)``{``    ``if` `(n == 0 || n == 1)``        ``return``;``    ``long` `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``long` `long` `fib(``long` `long` `n, ``long` `long` `m)``{``    ``long` `long` `F = { { 1, 1 }, { 1, 0 } };``    ``if` `(n == 0)``        ``return` `0;``    ``power(F, n - 1, m);``    ``return` `F;``}` `// 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

 ``
Output:
`27`

Time Complexity: log(n)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up