Find Nth term (A matrix exponentiation example)

27 May, 2021
We are given a recursive function that describes Nth terms in the form of other terms. In this article, we have taken specific examples. Now you are given n, and you have to find out nth term using the above formula.
Examples: 
Input : n = 2
Output : 5

Input : n = 3
Output :13 
Prerequisite : Basic Approach: This problem can be solved by simply just iterating over the n terms. Every time you find a term, using this term find the next one, and so on. But the time complexity of this problem is of order O(n).
Optimized Approach All such problems where a term is a function of other terms in a linear fashion. Then these can be solved using the Matrix (Please refer: Matrix Exponentiation ). First, we make a transformation matrix and then just use matrix exponentiation to find the Nth term.  
Step by Step method includes: 
Step 1. Determine k the number of terms on which T(i) depends. For our example, T(i) depends on two terms. So, k = 2
Step 2. Determine initial values As in this article T0=1, T1=1 are given.
Step 3. Determine TM, the transformation matrix. This is the most important step in solving recurrence relations. In this step, we have to make the matrix of dimension k*k. Such that T(i)=TM*(initial value vector)
Here initial value vector is the vector that contains an initial value. We name this vector as initial. 
Below is the program to implement the above approach. 
C++
Java
Python3
C#
PHP
Javascript
// CPP program to find n-th term of a recursive// function using matrix exponentiation.#include <bits/stdc++.h>using namespace std;#define MOD 1000000009 #define ll long long int ll power(ll n){    if (n <= 1)        return 1;     // This power function returns first row of    // {Transformation Matrix}^n-1*Initial Vector    n--;     // This is an identity matrix.    ll res[2][2] = { 1, 0, 0, 1 };     // this is Transformation matrix.    ll tMat[2][2] = { 2, 3, 1, 0 };     // Matrix exponentiation to calculate power of {tMat}^n-1    // store res in "res" matrix.    while (n) {         if (n & 1) {            ll tmp[2][2];            tmp[0][0] = (res[0][0] * tMat[0][0] + res[0][1] * tMat[1][0]) % MOD;            tmp[0][1] = (res[0][0] * tMat[0][1] + res[0][1] * tMat[1][1]) % MOD;            tmp[1][0] = (res[1][0] * tMat[0][0] + res[1][1] * tMat[1][0]) % MOD;            tmp[1][1] = (res[1][0] * tMat[0][1] + res[1][1] * tMat[1][1]) % MOD;            res[0][0] = tmp[0][0];            res[0][1] = tmp[0][1];            res[1][0] = tmp[1][0];            res[1][1] = tmp[1][1];        }        n = n / 2;        ll tmp[2][2];        tmp[0][0] = (tMat[0][0] * tMat[0][0] + tMat[0][1] * tMat[1][0]) % MOD;        tmp[0][1] = (tMat[0][0] * tMat[0][1] + tMat[0][1] * tMat[1][1]) % MOD;        tmp[1][0] = (tMat[1][0] * tMat[0][0] + tMat[1][1] * tMat[1][0]) % MOD;        tmp[1][1] = (tMat[1][0] * tMat[0][1] + tMat[1][1] * tMat[1][1]) % MOD;        tMat[0][0] = tmp[0][0];        tMat[0][1] = tmp[0][1];        tMat[1][0] = tmp[1][0];        tMat[1][1] = tmp[1][1];    }     // res store {Transformation matrix}^n-1    // hence will be first row of res*Initial Vector.    return (res[0][0] * 1 + res[0][1] * 1) % MOD;} // Driver codeint main(){    ll n = 3;    cout << power(n);    return 0;}
// Java program to find n-th term of a recursive// function using matrix exponentiation.class GfG {     static int MAX = 100;    static int MOD = 1000000009;    static int power(int n)    {        if (n <= 1) {            return 1;        }         // This power function returns first row of        // {Transformation Matrix}^n-1*Initial Vector        n--;         // This is an identity matrix.        int res[][] = { { 1, 0 }, { 0, 1 } };         // this is Transformation matrix.        int tMat[][] = { { 2, 3 }, { 1, 0 } };         // Matrix exponentiation to calculate power of {tMat}^n-1        // store res in "res" matrix.        while (n > 0) {             if (n % 2 == 1) {                int tmp[][] = new int[2][2];                tmp[0][0] = (res[0][0] * tMat[0][0]                             + res[0][1] * tMat[1][0])                            % MOD;                tmp[0][1] = (res[0][0] * tMat[0][1]                             + res[0][1] * tMat[1][1])                            % MOD;                tmp[1][0] = (res[1][0] * tMat[0][0]                             + res[1][1] * tMat[1][0])                            % MOD;                tmp[1][1] = (res[1][0] * tMat[0][1]                             + res[1][1] * tMat[1][1])                            % MOD;                res[0][0] = tmp[0][0];                res[0][1] = tmp[0][1];                res[1][0] = tmp[1][0];                res[1][1] = tmp[1][1];            }             n = n / 2;            int tmp[][] = new int[2][2];            tmp[0][0] = (tMat[0][0] * tMat[0][0]                         + tMat[0][1] * tMat[1][0])                        % MOD;            tmp[0][1] = (tMat[0][0] * tMat[0][1]                         + tMat[0][1] * tMat[1][1])                        % MOD;            tmp[1][0] = (tMat[1][0] * tMat[0][0]                         + tMat[1][1] * tMat[1][0])                        % MOD;            tmp[1][1] = (tMat[1][0] * tMat[0][1]                         + tMat[1][1] * tMat[1][1])                        % MOD;            tMat[0][0] = tmp[0][0];            tMat[0][1] = tmp[0][1];            tMat[1][0] = tmp[1][0];            tMat[1][1] = tmp[1][1];        }         // res store {Transformation matrix}^n-1        // hence wiint be first row of res*Initial Vector.        return (res[0][0] * 1 + res[0][1] * 1) % MOD;    }     // Driver code    public static void main(String[] args)    {        int n = 3;        System.out.println(power(n));    }} // This code contributed by Rajput-Ji
# Python3 program to find n-th term of a recursive# function using matrix exponentiation.MOD = 1000000009; def power(n):    if (n <= 1):        return 1;     # This power function returns first row of    # {Transformation Matrix}^n-1 * Initial Vector    n-= 1;     # This is an identity matrix.    res = [[1, 0], [0, 1]];     # this is Transformation matrix.    tMat = [[2, 3], [1, 0]];     # Matrix exponentiation to calculate    # power of {tMat}^n-1 store res in "res" matrix.    while (n):        if (n & 1):            tmp = [[0 for x in range(2)] for y in range(2)];            tmp[0][0] = (res[0][0] * tMat[0][0] +                        res[0][1] * tMat[1][0]) % MOD;            tmp[0][1] = (res[0][0] * tMat[0][1] +                        res[0][1] * tMat[1][1]) % MOD;            tmp[1][0] = (res[1][0] * tMat[0][0] +                        res[1][1] * tMat[1][0]) % MOD;            tmp[1][1] = (res[1][0] * tMat[0][1] +                        res[1][1] * tMat[1][1]) % MOD;            res[0][0] = tmp[0][0];            res[0][1] = tmp[0][1];            res[1][0] = tmp[1][0];            res[1][1] = tmp[1][1];             n = n // 2;        tmp = [[0 for x in range(2)] for y in range(2)];        tmp[0][0] = (tMat[0][0] * tMat[0][0] +                    tMat[0][1] * tMat[1][0]) % MOD;        tmp[0][1] = (tMat[0][0] * tMat[0][1] +                    tMat[0][1] * tMat[1][1]) % MOD;        tmp[1][0] = (tMat[1][0] * tMat[0][0] +                    tMat[1][1] * tMat[1][0]) % MOD;        tmp[1][1] = (tMat[1][0] * tMat[0][1] +                    tMat[1][1] * tMat[1][1]) % MOD;        tMat[0][0] = tmp[0][0];        tMat[0][1] = tmp[0][1];        tMat[1][0] = tmp[1][0];        tMat[1][1] = tmp[1][1];     # res store {Transformation matrix}^n-1    # hence will be first row of res * Initial Vector.    return (res[0][0] * 1 + res[0][1] * 1) % MOD; # Driver coden = 3;print(power(n));     # This code is contributed by mits
// C# program to find n-th term of a recursive// function using matrix exponentiation.using System; class GfG {     // static int MAX = 100;    static int MOD = 1000000009;    static int power(int n)    {        if (n <= 1) {            return 1;        }         // This power function returns first row of        // {Transformation Matrix}^n-1*Initial Vector        n--;         // This is an identity matrix.        int[, ] res = { { 1, 0 }, { 0, 1 } };         // this is Transformation matrix.        int[, ] tMat = { { 2, 3 }, { 1, 0 } };         // Matrix exponentiation to calculate power of {tMat}^n-1        // store res in "res" matrix.        while (n > 0) {             if (n % 2 == 1) {                int[, ] tmp = new int[2, 2];                tmp[0, 0] = (res[0, 0] * tMat[0, 0]                             + res[0, 1] * tMat[1, 0])                            % MOD;                tmp[0, 1] = (res[0, 0] * tMat[0, 1]                             + res[0, 1] * tMat[1, 1])                            % MOD;                tmp[1, 0] = (res[1, 0] * tMat[0, 0]                             + res[1, 1] * tMat[1, 0])                            % MOD;                tmp[1, 1] = (res[1, 0] * tMat[0, 1]                             + res[1, 1] * tMat[1, 1])                            % MOD;                res[0, 0] = tmp[0, 0];                res[0, 1] = tmp[0, 1];                res[1, 0] = tmp[1, 0];                res[1, 1] = tmp[1, 1];            }             n = n / 2;            int[, ] tmp1 = new int[2, 2];            tmp1[0, 0] = (tMat[0, 0] * tMat[0, 0]                          + tMat[0, 1] * tMat[1, 0])                         % MOD;            tmp1[0, 1] = (tMat[0, 0] * tMat[0, 1]                          + tMat[0, 1] * tMat[1, 1])                         % MOD;            tmp1[1, 0] = (tMat[1, 0] * tMat[0, 0]                          + tMat[1, 1] * tMat[1, 0])                         % MOD;            tmp1[1, 1] = (tMat[1, 0] * tMat[0, 1]                          + tMat[1, 1] * tMat[1, 1])                         % MOD;            tMat[0, 0] = tmp1[0, 0];            tMat[0, 1] = tmp1[0, 1];            tMat[1, 0] = tmp1[1, 0];            tMat[1, 1] = tmp1[1, 1];        }         // res store {Transformation matrix}^n-1        // hence wiint be first row of res*Initial Vector.        return (res[0, 0] * 1 + res[0, 1] * 1) % MOD;    }     // Driver code    public static void Main()    {        int n = 3;        Console.WriteLine(power(n));    }} // This code contributed by mits
<?php// PHP program to find n-th term of a recursive// function using matrix exponentiation.$MOD = 1000000009; function power($n){    global $MOD;    if ($n <= 1)        return 1;     // This power function returns first row of    // {Transformation Matrix}^n-1*Initial Vector    $n--;     // This is an identity matrix.    $res = array(array(1, 0), array(0, 1));     // this is Transformation matrix.    $tMat= array(array(2, 3), array(1, 0));     // Matrix exponentiation to calculate    // power of {tMat}^n-1 store res in "res" matrix.    while ($n)    {        if ($n & 1)        {            $tmp = array_fill(0, 2, array_fill(0, 2, 0));            $tmp[0][0] = ($res[0][0] * $tMat[0][0] +                          $res[0][1] * $tMat[1][0]) % $MOD;            $tmp[0][1] = ($res[0][0] * $tMat[0][1] +                          $res[0][1] * $tMat[1][1]) % $MOD;            $tmp[1][0] = ($res[1][0] * $tMat[0][0] +                          $res[1][1] * $tMat[1][0]) % $MOD;            $tmp[1][1] = ($res[1][0] * $tMat[0][1] +                          $res[1][1] * $tMat[1][1]) % $MOD;            $res[0][0] = $tmp[0][0];            $res[0][1] = $tmp[0][1];            $res[1][0] = $tmp[1][0];            $res[1][1] = $tmp[1][1];        }        $n = (int)($n / 2);        $tmp = array_fill(0, 2, array_fill(0, 2, 0));        $tmp[0][0] = ($tMat[0][0] * $tMat[0][0] +                      $tMat[0][1] * $tMat[1][0]) % $MOD;        $tmp[0][1] = ($tMat[0][0] * $tMat[0][1] +                      $tMat[0][1] * $tMat[1][1]) % $MOD;        $tmp[1][0] = ($tMat[1][0] * $tMat[0][0] +                      $tMat[1][1] * $tMat[1][0]) % $MOD;        $tmp[1][1] = ($tMat[1][0] * $tMat[0][1] +                      $tMat[1][1] * $tMat[1][1]) % $MOD;        $tMat[0][0] = $tmp[0][0];        $tMat[0][1] = $tmp[0][1];        $tMat[1][0] = $tmp[1][0];        $tMat[1][1] = $tmp[1][1];    }     // res store {Transformation matrix}^n-1    // hence will be first row of res*Initial Vector.    return ($res[0][0] * 1 + $res[0][1] * 1) % $MOD;} // Driver code$n = 3;echo power($n);     // This code is contributed by mits?>
<script> // Javascript program to find n-th term of a recursive// function using matrix exponentiation.var MOD = 1000000009; function power(n){    if (n <= 1)        return 1;     // This power function returns first row of    // {Transformation Matrix}^n-1*Initial Vector    n--;     // This is an identity matrix.    var res = [[1, 0,], [0, 1]];     // this is Transformation matrix.    var tMat = [[2, 3],[1, 0]];     // Matrix exponentiation to calculate power of {tMat}^n-1    // store res in "res" matrix.    while (n) {         if (n & 1) {            var tmp = Array.from(Array(2), ()=> Array(2));            tmp[0][0] = (res[0][0] * tMat[0][0] + res[0][1] * tMat[1][0]) % MOD;            tmp[0][1] = (res[0][0] * tMat[0][1] + res[0][1] * tMat[1][1]) % MOD;            tmp[1][0] = (res[1][0] * tMat[0][0] + res[1][1] * tMat[1][0]) % MOD;            tmp[1][1] = (res[1][0] * tMat[0][1] + res[1][1] * tMat[1][1]) % MOD;            res[0][0] = tmp[0][0];            res[0][1] = tmp[0][1];            res[1][0] = tmp[1][0];            res[1][1] = tmp[1][1];        }        n = parseInt(n / 2);        var tmp = Array.from(Array(2), ()=> Array(2));        tmp[0][0] = (tMat[0][0] * tMat[0][0] + tMat[0][1] * tMat[1][0]) % MOD;        tmp[0][1] = (tMat[0][0] * tMat[0][1] + tMat[0][1] * tMat[1][1]) % MOD;        tmp[1][0] = (tMat[1][0] * tMat[0][0] + tMat[1][1] * tMat[1][0]) % MOD;        tmp[1][1] = (tMat[1][0] * tMat[0][1] + tMat[1][1] * tMat[1][1]) % MOD;        tMat[0][0] = tmp[0][0];        tMat[0][1] = tmp[0][1];        tMat[1][0] = tmp[1][0];        tMat[1][1] = tmp[1][1];    }     // res store {Transformation matrix}^n-1    // hence will be first row of res*Initial Vector.    return (res[0][0] * 1 + res[0][1] * 1) % MOD;} // Driver codevar n = 3;document.write( power(n)); </script>
13
 
Time Complexity : O(Log n)The same idea is used to find n-th Fibonacci number in O(Log n) 
Rajput-Ji
Mithun Kumar
rutvik_56
matrix-exponentiation
Competitive Programming
Divide and Conquer
Matrix
Recursion
Recursion
Divide and Conquer
Matrix
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Most important type of Algorithms
The Ultimate Beginner's Guide For DSA
Find two numbers from their sum and XOR
Equal Sum and XOR of three Numbers
C++: Methods of code shortening in competitive programming
Merge Sort
QuickSort
Binary Search
Maximum and minimum of an array using minimum number of comparisons
Count Inversions in an array | Set 1 (Using Merge Sort)