Sudo Placement 2 | Matrix Series
Last Updated :
25 Apr, 2023
A Matrix series is defined as follows:
M, MT, M(MT), M(MT)2, M2(MT)3, M3(MT)5, M5(MT)8 . . . . . . . ., where M is a binary square matrix of size K x K (Binary Matrix is a special type of Matrix where each element of the matrix is either 0 or 1) and MT represents the transpose of Matrix M.
Given N and K, find the Nth term of the series. Prerequisites : Modular Exponentiation Examples:
Input : N = 2, K = 4
M = {
{1, 1},
{0, 1}
}
Output : [ 3 1]
[ 2 1]
Explanation:
The 4th term of the series is M2(MT)3 and the value of M2(MT)3
is {{3, 1}, {2, 1}}.
Input : N = 2, K = 5
M = {
{1, 1},
{0, 1}
}
Output : [7 2]
[3 1]
Explanation:
The 4th term of the series is M3(MT)5 and the value of M3(MT)5
is {{7, 2}, {3, 1}}.
Approach :
It can be observed that the powers of MT are 0, 1, 1, 2, 3, 5, 8….. for the 1st, 2nd, 3rd….. terms respectively. This pattern for the powers of MT is nothing but the Fibonacci series. Except for the first term, it can be seen that the powers of M also have the same pattern but, here the power of M is the same as the power of MT for the previous term.
Since in Kth term MT has a power of fibK, M has the power of fibK – 1. Where fibi represents the ith fibonacci number. Thus, for the Kth term (for K ? 1) of the series can be calculated as:
Sk = Mfib(k - 1)(MT) fib(K)
As Fibonacci values increase pretty fast the 45th Fibonacci number is close to 1010. So the Kth power cant be calculated by repeated multiplication of the matrices K times. To do this, efficiently we can calculate the Kth power of the matrix using an idea similar to Modular Exponentiation.
As in Modular Exponentiation, the power is divided by 2 at every step, here also we follow the same Divide and conquer strategy except the fact that here we don’t multiply numbers, instead, here multiplication of matrices is required which can be done in O(N3), where N is the size of the square matrix. Below program illustrate the above approach:
Implementation:
CPP
#include <bits/stdc++.h>
#define ll long long
#define mod 1000000007
using namespace std;
vector<vector< int > > multiply(vector<vector< int > > A,
vector<vector< int > > B)
{
int n = A.size();
vector<vector< int > > result(n, vector< int >(n, 0));
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
for ( int k = 0; k < n; k++) {
result[i][j] = (result[i][j] + (A[i][k] * B[k][j]) % mod) % mod;
}
}
}
return result;
}
vector<vector< int > > fastpower(vector<vector< int > > A, int n, ll K)
{
if (K == 1)
return A;
if (K & 1) {
return multiply(A, fastpower(A, n, K - 1));
}
vector<vector< int > > result = fastpower(A, n, K / 2);
return multiply(result, result);
}
vector<vector< int > > transpose(vector<vector< int > > A)
{
int N = A.size();
vector<vector< int > > transposeMatrix(N, vector< int >(N, 0));
for ( int i = 0; i < N; i++) {
for ( int j = 0; j < N; j++) {
transposeMatrix[i][j] = A[j][i];
}
}
return transposeMatrix;
}
void printMatrix(vector<vector< int > > A)
{
int n = A.size();
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
cout << A[i][j] << " " ;
}
cout << endl;
}
}
void getKthTerm(vector<vector< int > > M, int n, int K)
{
ll fibonacci[K + 1];
fibonacci[1] = 0ll;
fibonacci[2] = 1ll;
for ( int i = 3; i <= K; i++) {
fibonacci[i] = fibonacci[i - 1] + fibonacci[i - 2];
}
vector<vector< int > > transposeM = transpose(M);
if (K == 1) {
printMatrix(M);
}
else if (K == 2) {
printMatrix(transposeM);
}
else {
vector<vector< int > > MpowerFibKminusOne;
MpowerFibKminusOne = fastpower(M, n, fibonacci[K - 1]);
vector<vector< int > > MTransposePowerFibK;
MTransposePowerFibK = fastpower(transposeM, n, fibonacci[K]);
vector<vector< int > > kthTerm = multiply(MpowerFibKminusOne,
MTransposePowerFibK);
printMatrix(kthTerm);
}
}
int main()
{
int n, K;
n = 2;
K = 4;
vector<vector< int > > M{ { 1, 1 }, { 0, 1 } };
getKthTerm(M, n, K);
K = 5;
getKthTerm(M, n, K);
return 0;
}
|
Java
import java.util.*;
public class GFG {
static int mod = 1000000007 ;
static int [][] multiply( int [][] A, int [][] B)
{
int n = A.length;
int [][] result = new int [n][n];
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < n; j++) {
for ( int k = 0 ; k < n; k++) {
result[i][j]
= (result[i][j]
+ (A[i][k] * B[k][j]) % mod)
% mod;
}
}
}
return result;
}
static int [][] fastpower( int [][] A, int n, long K)
{
if (K == 1 )
return A;
if ((K & 1 ) != 0 ) {
return multiply(A, fastpower(A, n, K - 1 ));
}
int [][] result = fastpower(A, n, K / 2 );
return multiply(result, result);
}
static int [][] transpose( int [][] A)
{
int N = A.length;
int [][] transposeMatrix = new int [N][N];
for ( int i = 0 ; i < N; i++) {
for ( int j = 0 ; j < N; j++) {
transposeMatrix[i][j] = A[j][i];
}
}
return transposeMatrix;
}
static void printMatrix( int [][] A)
{
int n = A.length;
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < n; j++) {
System.out.print(A[i][j] + " " );
}
System.out.println();
}
}
static void getKthTerm( int [][] M, int n, int K)
{
long [] fibonacci = new long [K + 1 ];
fibonacci[ 1 ] = 0L;
fibonacci[ 2 ] = 1L;
for ( int i = 3 ; i <= K; i++) {
fibonacci[i]
= fibonacci[i - 1 ] + fibonacci[i - 2 ];
}
int [][] transposeM = transpose(M);
if (K == 1 ) {
printMatrix(M);
}
else if (K == 2 ) {
printMatrix(transposeM);
}
else {
int [][] MpowerFibKminusOne;
MpowerFibKminusOne
= fastpower(M, n, fibonacci[K - 1 ]);
int [][] MTransposePowerFibK;
MTransposePowerFibK
= fastpower(transposeM, n, fibonacci[K]);
int [][] kthTerm = multiply(MpowerFibKminusOne,
MTransposePowerFibK);
printMatrix(kthTerm);
}
}
public static void main(String[] args)
{
int n, K;
n = 2 ;
K = 4 ;
int [][] M = { { 1 , 1 }, { 0 , 1 } };
getKthTerm(M, n, K);
K = 5 ;
getKthTerm(M, n, K);
}
}
|
Python3
mod = 1000000007 ;
def multiply(A, B):
n = len (A);
result = [[ 0 ] * n for _ in range (n)]
for i in range (n):
for j in range (n):
for k in range (n):
result[i][j] = (result[i][j] + (A[i][k] * B[k][j]) % mod) % mod;
return result;
def fastpower(A, n, K):
if (K = = 1 ):
return A;
if (K & 1 ! = 0 ) :
return multiply(A, fastpower(A, n, K - 1 ));
result = fastpower(A, n, int (K / 2 ));
return multiply(result, result);
def transpose(A):
N = len (A);
transposeMatrix = [[ 0 ] * n for _ in range (n)]
for i in range (N):
for j in range (N):
transposeMatrix[i][j] = A[j][i];
return transposeMatrix;
def printMatrix(A):
n = len (A);
for i in range (n):
print ( * A[i])
def getKthTerm(M, n, K):
fibonacci = [ 0 ] * (K + 1 )
fibonacci[ 1 ] = 0 ;
fibonacci[ 2 ] = 1 ;
for i in range ( 3 , 1 + K):
fibonacci[i] = fibonacci[i - 1 ] + fibonacci[i - 2 ];
transposeM = transpose(M);
if (K = = 1 ):
printMatrix(M);
elif (K = = 2 ):
printMatrix(transposeM);
else :
MpowerFibKminusOne = fastpower(M, n, fibonacci[K - 1 ]);
MTransposePowerFibK = fastpower(transposeM, n, fibonacci[K]);
kthTerm = multiply(MpowerFibKminusOne, MTransposePowerFibK);
printMatrix(kthTerm);
n = 2 ;
K = 4 ;
M = [[ 1 , 1 ], [ 0 , 1 ]];
getKthTerm(M, n, K);
K = 5 ;
getKthTerm(M, n, K);
|
C#
using System;
using System.Collections.Generic;
public class GFG {
static int mod = 1000000007;
static int [][] multiply( int [][] A, int [][] B)
{
int n = A.Length;
int [][] result = new int [n][];
for ( int i = 0; i < n; i++) {
result[i] = new int [n];
for ( int j = 0; j < n; j++) {
for ( int k = 0; k < n; k++) {
result[i][j]
= (result[i][j]
+ (A[i][k] * B[k][j]) % mod)
% mod;
}
}
}
return result;
}
static int [][] fastpower( int [][] A, int n, long K)
{
if (K == 1)
return A;
if ((K & 1) != 0) {
return multiply(A, fastpower(A, n, K - 1));
}
int [][] result = fastpower(A, n, K / 2);
return multiply(result, result);
}
static int [][] transpose( int [][] A)
{
int N = A.Length;
int [][] transposeMatrix = new int [N][];
for ( int i = 0; i < N; i++) {
transposeMatrix[i] = new int [N];
for ( int j = 0; j < N; j++) {
transposeMatrix[i][j] = A[j][i];
}
}
return transposeMatrix;
}
static void printMatrix( int [][] A)
{
int n = A.Length;
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
Console.Write(A[i][j] + " " );
}
Console.WriteLine();
}
}
static void getKthTerm( int [][] M, int n, int K)
{
long [] fibonacci = new long [K + 1];
fibonacci[1] = 0L;
fibonacci[2] = 1L;
for ( int i = 3; i <= K; i++) {
fibonacci[i]
= fibonacci[i - 1] + fibonacci[i - 2];
}
int [][] transposeM = transpose(M);
if (K == 1) {
printMatrix(M);
}
else if (K == 2) {
printMatrix(transposeM);
}
else {
int [][] MpowerFibKminusOne;
MpowerFibKminusOne
= fastpower(M, n, fibonacci[K - 1]);
int [][] MTransposePowerFibK;
MTransposePowerFibK
= fastpower(transposeM, n, fibonacci[K]);
int [][] kthTerm = multiply(MpowerFibKminusOne,
MTransposePowerFibK);
printMatrix(kthTerm);
}
}
public static void Main( string [] args)
{
int n, K;
n = 2;
K = 4;
int [][] M = { new int [] { 1, 1 }, new int [] { 0, 1 } };
getKthTerm(M, n, K);
K = 5;
getKthTerm(M, n, K);
}
}
|
Javascript
let mod = 1000000007;
function multiply(A, B)
{
let n = A.length;
let result = new Array(n);
for (let i = 0; i < n; i++){
result[i] = new Array(n).fill(0);
}
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
for (let k = 0; k < n; k++) {
result[i][j] = (result[i][j] + (A[i][k] * B[k][j]) % mod) % mod;
}
}
}
return result;
}
function fastpower(A, n, K)
{
if (K == 1)
return A;
if (K & 1 != 0) {
return multiply(A, fastpower(A, n, K - 1));
}
let result = fastpower(A, n, Math.floor(K / 2));
return multiply(result, result);
}
function transpose(A)
{
let N = A.length;
let transposeMatrix = new Array(N);
for (let i = 0; i < N; i++){
transposeMatrix[i] = new Array(N).fill(0);
}
for (let i = 0; i < N; i++) {
for (let j = 0; j < N; j++) {
transposeMatrix[i][j] = A[j][i];
}
}
return transposeMatrix;
}
function printMatrix(A)
{
let n = A.length;
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
document.write(A[i][j] + " " );
}
document.write( "\n" );
}
}
function getKthTerm(M, n, K)
{
let fibonacci = new Array(K+1).fill(0);
fibonacci[1] = 0;
fibonacci[2] = 1;
for (let i = 3; i <= K; i++) {
fibonacci[i] = fibonacci[i - 1] + fibonacci[i - 2];
}
let transposeM = transpose(M);
if (K == 1) {
printMatrix(M);
}
else if (K == 2) {
printMatrix(transposeM);
}
else {
let MpowerFibKminusOne;
MpowerFibKminusOne = fastpower(M, n, fibonacci[K - 1]);
let MTransposePowerFibK;
MTransposePowerFibK = fastpower(transposeM, n, fibonacci[K]);
let kthTerm = multiply(MpowerFibKminusOne, MTransposePowerFibK);
printMatrix(kthTerm);
}
}
let n, K;
n = 2;
K = 4;
let M = [[1, 1 ], [0, 1]];
getKthTerm(M, n, K);
K = 5;
getKthTerm(M, n, K);
|
Time Complexity: O(N3K), where N is the size of the square matrix, and K is the power to which it is raised.
Auxiliary Space: O(K), where K is the power to which the matrix is raised.
Share your thoughts in the comments
Please Login to comment...