Given a 2 × 2 matrix: A = [[1, 1], [1, 0]] and an integer n. Compute the matrix An. Return the value of the element at position A[1][0] (i.e., second row, first column) modulo 109 + 7.
Examples:
Input: n = 3
Output: 2
Explanation: For n = 3, we start with the matrix A = [[1, 1], [1, 0]] and compute its cube, A³. First, we find A² by multiplying A with itself, which gives A² = [[2, 1], [1, 1]]. Then, we multiply A² with A to get A³ = [[3, 2], [2, 1]].
From this resulting matrix, we take the element at position A[1][0] (second row, first column), which is 2. Hence, the output is 2.Input: n = 4
Output: 3
Explanation: For n = 4, we start with the matrix A = [[1, 1], [1, 0]] and compute its fourth power A4. First, we find A² by multiplying A with itself, which gives A² = [[2, 1], [1, 1]].
Next, we multiply A² with A to obtain A³ = [[3, 2], [2, 1]]. Then, multiplying A³ with A again gives A4 = [[5, 3], [3, 2]]. From this resulting matrix, we take the element at position A[1][0] (second row, first column), which is 3. Hence, the output is 3.
Table of Content
[Naive Approach] Repeated Matrix Multiplication - O(n) Time and O(1) Space
The idea is to multiply the matrix A by itself repeatedly using a loop that runs n times.
After getting the required power, return the element at position [1][0].
Working of Approach:
- Start with the given matrix A = [[1, 1], [1, 0]].
- Multiply the current matrix by A for n - 1 times.
- Perform every multiplication modulo 10^9 + 7.
- After obtaining A^n, return the element at position [1][0].
#include <iostream>
using namespace std;
const int MOD = 1000000007;
// Multiplies two 2 x 2 matrices and stores the result in A
void multiply(int A[2][2], int B[2][2])
{
int temp[2][2];
// Calculate each element of the resulting matrix
temp[0][0] = (1LL * A[0][0] * B[0][0] + 1LL * A[0][1] * B[1][0]) % MOD;
temp[0][1] = (1LL * A[0][0] * B[0][1] + 1LL * A[0][1] * B[1][1]) % MOD;
temp[1][0] = (1LL * A[1][0] * B[0][0] + 1LL * A[1][1] * B[1][0]) % MOD;
temp[1][1] = (1LL * A[1][0] * B[0][1] + 1LL * A[1][1] * B[1][1]) % MOD;
// Copy the result back into A
A[0][0] = temp[0][0];
A[0][1] = temp[0][1];
A[1][0] = temp[1][0];
A[1][1] = temp[1][1];
}
int firstElement(int n)
{
// Given matrix A
int result[2][2] = {{1, 1}, {1, 0}};
// Multiply A by itself n - 1 times
for (int i = 2; i <= n; i++)
{
int base[2][2] = {{1, 1}, {1, 0}};
multiply(result, base);
}
// Return the element at position [1][0]
return result[1][0];
}
int main()
{
cout << firstElement(3) << "\n";
cout << firstElement(4) << "\n";
return 0;
}
import java.util.*;
public class GFG {
static final int MOD = 1000000007;
// Multiplies two 2 x 2 matrices and stores the result
// in A
static void multiply(int A[][], int B[][])
{
int temp[][] = new int[2][2];
// Calculate each element of the resulting matrix
temp[0][0] = (int)((1L * A[0][0] * B[0][0]
+ 1L * A[0][1] * B[1][0])
% MOD);
temp[0][1] = (int)((1L * A[0][0] * B[0][1]
+ 1L * A[0][1] * B[1][1])
% MOD);
temp[1][0] = (int)((1L * A[1][0] * B[0][0]
+ 1L * A[1][1] * B[1][0])
% MOD);
temp[1][1] = (int)((1L * A[1][0] * B[0][1]
+ 1L * A[1][1] * B[1][1])
% MOD);
// Copy the result back into A
A[0][0] = temp[0][0];
A[0][1] = temp[0][1];
A[1][0] = temp[1][0];
A[1][1] = temp[1][1];
}
static int firstElement(int n)
{
// Given matrix A
int result[][] = { { 1, 1 }, { 1, 0 } };
// Multiply A by itself n - 1 times
for (int i = 2; i <= n; i++) {
int base[][] = { { 1, 1 }, { 1, 0 } };
multiply(result, base);
}
// Return the element at position [1][0]
return result[1][0];
}
public static void main(String[] args)
{
System.out.println(firstElement(3));
System.out.println(firstElement(4));
}
}
MOD = 1000000007
# Multiplies two 2 x 2 matrices and stores the result in A
def multiply(A, B):
temp = [[0, 0], [0, 0]]
# Calculate each element of the resulting matrix
temp[0][0] = (1 * A[0][0] * B[0][0] + 1 * A[0][1] * B[1][0]) % MOD
temp[0][1] = (1 * A[0][0] * B[0][1] + 1 * A[0][1] * B[1][1]) % MOD
temp[1][0] = (1 * A[1][0] * B[0][0] + 1 * A[1][1] * B[1][0]) % MOD
temp[1][1] = (1 * A[1][0] * B[0][1] + 1 * A[1][1] * B[1][1]) % MOD
# Copy the result back into A
A[0][0] = temp[0][0]
A[0][1] = temp[0][1]
A[1][0] = temp[1][0]
A[1][1] = temp[1][1]
def firstElement(n):
# Given matrix A
result = [[1, 1], [1, 0]]
# Multiply A by itself n - 1 times
for i in range(2, n + 1):
base = [[1, 1], [1, 0]]
multiply(result, base)
# Return the element at position [1][0]
return result[1][0]
if __name__ == '__main__':
print(firstElement(3))
print(firstElement(4))
using System;
class GFG {
const int MOD = 1000000007;
// Multiplies two 2 x 2 matrices and stores the result
// in A
static void multiply(int[, ] A, int[, ] B)
{
int[, ] temp = new int[2, 2];
// Calculate each element of the resulting matrix
temp[0, 0] = (int)((1L * A[0, 0] * B[0, 0]
+ 1L * A[0, 1] * B[1, 0])
% MOD);
temp[0, 1] = (int)((1L * A[0, 0] * B[0, 1]
+ 1L * A[0, 1] * B[1, 1])
% MOD);
temp[1, 0] = (int)((1L * A[1, 0] * B[0, 0]
+ 1L * A[1, 1] * B[1, 0])
% MOD);
temp[1, 1] = (int)((1L * A[1, 0] * B[0, 1]
+ 1L * A[1, 1] * B[1, 1])
% MOD);
// Copy the result back into A
A[0, 0] = temp[0, 0];
A[0, 1] = temp[0, 1];
A[1, 0] = temp[1, 0];
A[1, 1] = temp[1, 1];
}
static int firstElement(int n)
{
// Given matrix A
int[, ] result = new int[, ] { { 1, 1 }, { 1, 0 } };
// Multiply A by itself n - 1 times
for (int i = 2; i <= n; i++) {
int[, ] baseMatrix
= new int[, ] { { 1, 1 }, { 1, 0 } };
multiply(result, baseMatrix);
}
// Return the element at position [1][0]
return result[1, 0];
}
static void Main()
{
Console.WriteLine(firstElement(3));
Console.WriteLine(firstElement(4));
}
}
const MOD = 1000000007;
// Multiplies two 2 x 2 matrices and stores the result in A
function multiply(A, B)
{
let temp = [ [ 0, 0 ], [ 0, 0 ] ];
// Calculate each element of the resulting matrix
temp[0][0] = (1n * BigInt(A[0][0]) * BigInt(B[0][0])
+ 1n * BigInt(A[0][1]) * BigInt(B[1][0]))
% BigInt(MOD);
temp[0][1] = (1n * BigInt(A[0][0]) * BigInt(B[0][1])
+ 1n * BigInt(A[0][1]) * BigInt(B[1][1]))
% BigInt(MOD);
temp[1][0] = (1n * BigInt(A[1][0]) * BigInt(B[0][0])
+ 1n * BigInt(A[1][1]) * BigInt(B[1][0]))
% BigInt(MOD);
temp[1][1] = (1n * BigInt(A[1][0]) * BigInt(B[0][1])
+ 1n * BigInt(A[1][1]) * BigInt(B[1][1]))
% BigInt(MOD);
// Copy the result back into A
A[0][0] = temp[0][0];
A[0][1] = temp[0][1];
A[1][0] = temp[1][0];
A[1][1] = temp[1][1];
}
function firstElement(n)
{
// Given matrix A
let result = [ [ 1, 1 ], [ 1, 0 ] ];
// Multiply A by itself n - 1 times
for (let i = 2; i <= n; i++) {
let base = [ [ 1, 1 ], [ 1, 0 ] ];
multiply(result, base);
}
// Return the element at position [1][0]
return result[1][0];
}
// Driver Code
console.log(firstElement(3));
console.log(firstElement(4));
Output
2 3
[Expected Approach] Matrix Exponentiation - O(log n) Time and O(1) Space
To calculate (An), we have 3 possible positive values of n:
- Case 1: If n = 0, whatever be the value of A, our result will be Identity Matrix I.
- Case 2: If n is an even number, then instead of calculating (An), we can calculate ((A2)n/2) and the result will be same.
- Case 3: If n is an odd number, we calculate (A * (A(n – 1)/2)2).
Let us understand with an example:
Input: n = 3
- Initialize result = [[1, 0], [0, 1]] and base = [[1, 1], [1, 0]], then set n = 2.
- Since n is even, square base to get [[2, 1], [1, 1]], then set n = 1.
- Since n is odd, multiply result by base, so result = [[2, 1], [1, 1]].
- Square base and set n = 0, ending the loop.
- Return result[0][0] = 2, which is the required element A³[1][0].
#include <iostream>
using namespace std;
const int MOD = 1000000007;
// Multiplies two 2 x 2 matrices and stores the result in A
void multiply(int A[2][2], int B[2][2])
{
int temp[2][2];
// Calculate each element of the resulting matrix
temp[0][0] = (1LL * A[0][0] * B[0][0] + 1LL * A[0][1] * B[1][0]) % MOD;
temp[0][1] = (1LL * A[0][0] * B[0][1] + 1LL * A[0][1] * B[1][1]) % MOD;
temp[1][0] = (1LL * A[1][0] * B[0][0] + 1LL * A[1][1] * B[1][0]) % MOD;
temp[1][1] = (1LL * A[1][0] * B[0][1] + 1LL * A[1][1] * B[1][1]) % MOD;
// Copy the result back into A
A[0][0] = temp[0][0];
A[0][1] = temp[0][1];
A[1][0] = temp[1][0];
A[1][1] = temp[1][1];
}
int firstElement(int n)
{
// Handle the first power separately
if (n == 0)
return 0;
// Identity matrix
int result[2][2] = {{1, 0}, {0, 1}};
// Given matrix A
int base[2][2] = {{1, 1}, {1, 0}};
// Calculate A^(n - 1)
n = n - 1;
// Apply binary exponentiation
while (n > 0)
{
// If the current power is odd, multiply result by base
if (n % 2 == 1)
{
multiply(result, base);
}
// Square the base matrix
multiply(base, base);
// Move to the next bit
n /= 2;
}
// A^(n - 1)[0][0] equals A^n[1][0]
return result[0][0];
}
int main()
{
cout << firstElement(3) << "\n";
cout << firstElement(4) << "\n";
return 0;
}
import java.util.*;
public class GFG {
static final int MOD = 1000000007;
// Multiplies two 2 x 2 matrices and stores the result
// in A
static void multiply(int[][] A, int[][] B)
{
int[][] temp = new int[2][2];
temp[0][0] = (int)((1L * A[0][0] * B[0][0]
+ 1L * A[0][1] * B[1][0])
% MOD);
temp[0][1] = (int)((1L * A[0][0] * B[0][1]
+ 1L * A[0][1] * B[1][1])
% MOD);
temp[1][0] = (int)((1L * A[1][0] * B[0][0]
+ 1L * A[1][1] * B[1][0])
% MOD);
temp[1][1] = (int)((1L * A[1][0] * B[0][1]
+ 1L * A[1][1] * B[1][1])
% MOD);
A[0][0] = temp[0][0];
A[0][1] = temp[0][1];
A[1][0] = temp[1][0];
A[1][1] = temp[1][1];
}
static int firstElement(int n)
{
if (n == 0)
return 0;
int[][] result = { { 1, 0 }, { 0, 1 } };
int[][] base = { { 1, 1 }, { 1, 0 } };
n = n - 1;
while (n > 0) {
if (n % 2 == 1) {
multiply(result, base);
}
multiply(base, base);
n /= 2;
}
return result[0][0];
}
public static void main(String[] args)
{
System.out.println(firstElement(3));
System.out.println(firstElement(4));
}
}
MOD = 1000000007
# Multiplies two 2 x 2 matrices and stores the result in A
def multiply(A, B):
temp = [[0, 0], [0, 0]]
temp[0][0] = (1 * A[0][0] * B[0][0] + 1 * A[0][1] * B[1][0]) % MOD
temp[0][1] = (1 * A[0][0] * B[0][1] + 1 * A[0][1] * B[1][1]) % MOD
temp[1][0] = (1 * A[1][0] * B[0][0] + 1 * A[1][1] * B[1][0]) % MOD
temp[1][1] = (1 * A[1][0] * B[0][1] + 1 * A[1][1] * B[1][1]) % MOD
A[0][0] = temp[0][0]
A[0][1] = temp[0][1]
A[1][0] = temp[1][0]
A[1][1] = temp[1][1]
def firstElement(n):
if n == 0:
return 0
result = [[1, 0], [0, 1]]
base = [[1, 1], [1, 0]]
n = n - 1
while n > 0:
if n % 2 == 1:
multiply(result, base)
multiply(base, base)
n //= 2
return result[0][0]
if __name__ == '__main__':
print(firstElement(3))
print(firstElement(4))
using System;
class GFG {
const int MOD = 1000000007;
// Multiplies two 2 x 2 matrices and stores the result
// in A
static void multiply(int[, ] A, int[, ] B)
{
int[, ] temp = new int[2, 2];
// Calculate each element of the resulting matrix
temp[0, 0] = (int)((1L * A[0, 0] * B[0, 0]
+ 1L * A[0, 1] * B[1, 0])
% MOD);
temp[0, 1] = (int)((1L * A[0, 0] * B[0, 1]
+ 1L * A[0, 1] * B[1, 1])
% MOD);
temp[1, 0] = (int)((1L * A[1, 0] * B[0, 0]
+ 1L * A[1, 1] * B[1, 0])
% MOD);
temp[1, 1] = (int)((1L * A[1, 0] * B[0, 1]
+ 1L * A[1, 1] * B[1, 1])
% MOD);
// Copy the result back into A
A[0, 0] = temp[0, 0];
A[0, 1] = temp[0, 1];
A[1, 0] = temp[1, 0];
A[1, 1] = temp[1, 1];
}
static int firstElement(int n)
{
// Identity matrix
int[, ] result = new int[, ] { { 1, 0 }, { 0, 1 } };
// Given matrix A
int[, ] baseMatrix
= new int[, ] { { 1, 1 }, { 1, 0 } };
// Calculate A^(n - 1)
n = n - 1;
// Apply binary exponentiation
while (n > 0) {
// If the current power is odd, multiply result
// by base
if (n % 2 == 1) {
multiply(result, baseMatrix);
}
// Square the base matrix
multiply(baseMatrix, baseMatrix);
// Move to the next bit
n /= 2;
}
// A^(n - 1)[0][0] equals A^n[1][0]
return result[0, 0];
}
static void Main(string[] args)
{
Console.WriteLine(firstElement(3));
Console.WriteLine(firstElement(4));
}
}
const MOD = 1000000007;
// Multiplies two 2 x 2 matrices and stores the result in A
function multiply(A, B)
{
let temp = [ [ 0, 0 ], [ 0, 0 ] ];
// Calculate each element of the resulting matrix
temp[0][0] = (1n * BigInt(A[0][0]) * BigInt(B[0][0])
+ 1n * BigInt(A[0][1]) * BigInt(B[1][0]))
% BigInt(MOD);
temp[0][1] = (1n * BigInt(A[0][0]) * BigInt(B[0][1])
+ 1n * BigInt(A[0][1]) * BigInt(B[1][1]))
% BigInt(MOD);
temp[1][0] = (1n * BigInt(A[1][0]) * BigInt(B[0][0])
+ 1n * BigInt(A[1][1]) * BigInt(B[1][0]))
% BigInt(MOD);
temp[1][1] = (1n * BigInt(A[1][0]) * BigInt(B[0][1])
+ 1n * BigInt(A[1][1]) * BigInt(B[1][1]))
% BigInt(MOD);
// Copy the result back into A
A[0][0] = Number(temp[0][0]);
A[0][1] = Number(temp[0][1]);
A[1][0] = Number(temp[1][0]);
A[1][1] = Number(temp[1][1]);
}
function firstElement(n)
{
// Handle the first power separately
if (n === 0)
return 0;
// Identity matrix
let result = [ [ 1, 0 ], [ 0, 1 ] ];
// Given matrix A
let base = [ [ 1, 1 ], [ 1, 0 ] ];
// Calculate A^(n - 1)
n = n - 1;
// Apply binary exponentiation
while (n > 0) {
// If the current power is odd, multiply result by
// base
if (n % 2 === 1) {
multiply(result, base);
}
// Square the base matrix
multiply(base, base);
// Move to the next bit
n = Math.floor(n / 2);
}
// A^(n - 1)[0][0] equals A^n[1][0]
return result[0][0];
}
// Driver Code
console.log(firstElement(3));
console.log(firstElement(4));
Output
2 3