# Sudo Placement 2 | Matrix Series

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}}.
```

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

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 divider 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:

 `// CPP code to find Kth term of the Matrix Series ` `#include ` ` `  `#define ll long long ` `#define mod 1000000007 ` ` `  `using` `namespace` `std; ` ` `  `// This function multiplies two matrices A and B, under modulo mod ` `// and returns the resultant matrix after multiplication ` `vector > multiply(vector > A, ` `                              ``vector > B) ` `{ ` ` `  `    ``// n is the size of the matrix ` `    ``int` `n = A.size(); ` ` `  `    ``// Resultant matrix formded after multiplying matrix A and B ` `    ``vector > result(n, vector<``int``>(n, 0)); ` ` `  `    ``// Matrix Multiplication ` `    ``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; ` `} ` ` `  `// Function to find the Kth power of matrix A of size nXn in O(logK) ` `// similar to Modular Exponentiation ` `vector > fastpower(vector > A, ``int` `n, ll K) ` `{ ` `    ``// Base Case ` `    ``if` `(K == 1) ` `        ``return` `A; ` ` `  `    ``// Recursive Case1: If power is Odd ` `    ``if` `(K & 1) { ` `        ``// power(A, K) = power(A, K/2) * power(A, K/2) * A ` `        ``// when K is odd, Note than in this implementation ` `        ``// multiply (power(A, K - 1) * A) as in the case ` `        ``// the power becomes even in the next recursive call ` `        ``return` `multiply(A, fastpower(A, n, K - 1)); ` `    ``} ` ` `  `    ``// power(A, K) = power(A, K/2) * power(A, K/2) if K is even ` `    ``vector > result = fastpower(A, n, K / 2); ` `    ``return` `multiply(result, result); ` `} ` ` `  `// Returns the transpose of the matrix A ` `vector > transpose(vector > A) ` `{ ` `    ``int` `N = A.size(); ` `    ``vector > 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; ` `} ` ` `  `// Prints the matrix A ` `void` `printMatrix(vector > 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; ` `    ``} ` `} ` ` `  `// Return the Kth term of the series where matrix M ` `// is a boolean matrix of size n X n ` `void` `getKthTerm(vector > M, ``int` `n, ``int` `K) ` `{ ` ` `  `    ``// precompue fibonacci till the Kth term ` `    ``ll fibonacci[K + 1]; ` ` `  `    ``// ith fibonacci number denotes the power of M' in ` `    ``// the ith term, M' represents the transpose of M ` `    ``// 1st term has power of M' as 0 thus fib = 1 ` `    ``fibonacci = 0ll; ` `    ``fibonacci = 1ll; ` `    ``for` `(``int` `i = 3; i <= K; i++) { ` `        ``fibonacci[i] = fibonacci[i - 1] + fibonacci[i - 2]; ` `    ``} ` ` `  `    ``// stores the transpose of Matrix M ` `    ``vector > transposeM = transpose(M); ` ` `  `    ``// K = 1 and K = 2, is handled separately ` `    ``if` `(K == 1) { ` `        ``printMatrix(M); ` `    ``} ` `    ``else` `if` `(K == 2) { ` `        ``printMatrix(transposeM); ` `    ``} ` ` `  `    ``else` `{ ` `        ``vector > MpowerFibKminusOne; ` `        ``MpowerFibKminusOne = fastpower(M, n, fibonacci[K - 1]); ` ` `  `        ``vector > MTransposePowerFibK; ` `        ``MTransposePowerFibK = fastpower(transposeM, n, fibonacci[K]); ` ` `  `        ``// kthTerm = (M^fib[K - 1]) * (transposeM ^ fib[K]) ` `        ``vector > kthTerm = multiply(MpowerFibKminusOne, ` `                                                ``MTransposePowerFibK); ` ` `  `        ``// Print the Resultant Matrix ` `        ``printMatrix(kthTerm); ` `    ``} ` `} ` ` `  `// Driver Code ` `int` `main() ` `{ ` ` `  `    ``int` `n, K; ` `    ``n = 2; ` `    ``K = 4; ` `    ``vector > M{ { 1, 1 }, { 0, 1 } }; ` `    ``getKthTerm(M, n, K); ` ` `  `    ``// prints the 5th term ` `    ``K = 5; ` `    ``getKthTerm(M, n, K); ` ` `  `    ``return` `0; ` `} ` `  `

Output :

```3 1
2 1
7 2
3 1
```

GeeksforGeeks has prepared a complete interview preparation course with premium videos, theory, practice problems, TA support and many more features. Please refer Placement 100 for details

My Personal Notes arrow_drop_up

This article is contributed by Team GeeksforGeeks. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.

Article Tags :

Be the First to upvote.

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.