Nth term of a recurrence relation generated by two given arrays
Given an integer N and two arrays F[] and C[] of size K that represent the first K terms and coefficient of first K terms of the below recurrence relation respectively.
FN = C1*FN – 1 + C2*FN – 2 + C3*FN – 3 +….+ CK*FN – K.
The task is to find the Nth term of the recurrence relation. Since the number can be very large take modulo to 109 + 7.
Examples:
Input: N = 10, K = 2, F[] = {0, 1}, C[] = {1, 1}
Output: 55
Explanation:
FN= FN – 1 + FN – 2 with F0 = 0, F1 = 1
The above recurrence relation forms the Fibonacci sequence with two initial values.
The remaining terms of the series can be calculated as the sum of previous K terms with corresponding multiplication with coefficient stored in C[].
Therefore, F10 = 55.Input: N = 5, K = 3, F[] = {1, 2, 3}, C[] = {1, 1, 1}
Output: 20
Explanation:
The sequence of the above recurrence relation is 1, 2, 3, 6, 11, 20, 37, 68, ….
Every next term is the sum of the previous (K = 3) terms with base condition F0 = 1, F1 = 2 and F2 = 3
Therefore, F5 = 20.
Naive Approach: The idea is to generate the sequence using the given recurrence relation by calculating each term with the help of the previous K terms. Print the Nth Term after the sequence is formed.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; int mod = 1e9 + 7; // Function to calculate Nth term of // general recurrence relations void NthTerm( int F[], int C[], int K, int n) { // Stores the generated sequence int ans[n + 1] = { 0 }; for ( int i = 0; i < K; i++) ans[i] = F[i]; for ( int i = K; i <= n; i++) { for ( int j = i - K; j < i; j++) { // Current term is sum of // previous k terms ans[i] += ans[j]; ans[i] %= mod; } } // Print the nth term cout << ans[n] << endl; } // Driver Code int main() { // Given Array F[] and C[] int F[] = { 0, 1 }; int C[] = { 1, 1 }; // Given N and K int K = 2; int N = 10; // Function Call NthTerm(F, C, K, N); return 0; } |
Java
// Java program for the above approach import java.util.*; import java.lang.*; class GFG{ static double mod = 1e9 + 7 ; // Function to calculate Nth term of // general recurrence relations static void NthTerm( int F[], int C[], int K, int n) { // Stores the generated sequence int ans[] = new int [n + 1 ]; for ( int i = 0 ; i < K; i++) ans[i] = F[i]; for ( int i = K; i <= n; i++) { for ( int j = i - K; j < i; j++) { // Current term is sum of // previous k terms ans[i] += ans[j]; ans[i] %= mod; } } // Print the nth term System.out.println(ans[n]); } // Driver Code public static void main (String[] args) { // Given Array F[] and C[] int F[] = { 0 , 1 }; int C[] = { 1 , 1 }; // Given N and K int K = 2 ; int N = 10 ; // Function call NthTerm(F, C, K, N); } } // This code is contributed by jana_sayantan |
Python3
# Python3 program for the above approach mod = 1e9 + 7 # Function to calculate Nth term of # general recurrence relations def NthTerm(F, C, K, n): # Stores the generated sequence ans = [ 0 ] * (n + 1 ) i = 0 while i < K: ans[i] = F[i] i + = 1 i = K while i < = n: j = i - K while j < i: # Current term is sum of # previous k terms ans[i] + = ans[j] ans[i] % = mod j + = 1 i + = 1 # Print the nth term print ( int (ans[n])) # Driver code if __name__ = = '__main__' : # Given Array F[] and C[] F = [ 0 , 1 ] C = [ 1 , 1 ] # Given N and K K = 2 N = 10 # Function call NthTerm(F, C, K, N) # This code is contributed by jana_sayantan |
C#
// C# program for // the above approach using System; class GFG{ static double mod = 1e9 + 7; // Function to calculate Nth term of // general recurrence relations static void NthTerm( int [] F, int [] C, int K, int n) { // Stores the generated sequence int []ans = new int [n + 1]; for ( int i = 0; i < K; i++) ans[i] = F[i]; for ( int i = K; i <= n; i++) { for ( int j = i - K; j < i; j++) { // Current term is sum of // previous k terms ans[i] += ans[j]; ans[i] %= ( int )mod; } } // Print the nth term Console.WriteLine(ans[n]); } // Driver Code public static void Main (String[] args) { // Given Array F[] and C[] int [] F= {0, 1}; int [] C= {1, 1}; // Given N and K int K = 2; int N = 10; // Function call NthTerm(F, C, K, N); } } // This code is contributed by jana_sayantan |
Javascript
<script> // JavaScript program for the above approach let mod = 1e9 + 7; // Function to calculate Nth term of // general recurrence relations function NthTerm(F, C, K, n) { // Stores the generated sequence let ans = new Uint8Array(n + 1); for (let i = 0; i < K; i++) ans[i] = F[i]; for (let i = K; i <= n; i++) { for (let j = i - K; j < i; j++) { // Current term is sum of // previous k terms ans[i] += ans[j]; ans[i] %= mod; } } // Print the nth term document.write(ans[n] + "<br>" ); } // Driver Code // Given Array F[] and C[] let F = [ 0, 1 ]; let C = [ 1, 1 ]; // Given N and K let K = 2; let N = 10; // Function Call NthTerm(F, C, K, N); // This code is contributed by Surbhi Tyagi. </script> |
55
Time Complexity: O(N2)
Auxiliary Space: O(N)
Efficient Approach: The Nth term of the recurrence relation can be found by using Matrix Exponentiation. Below are the steps:
- Let’s consider the initial states as:
F = [f0, f1, f2…………………………………fk-1]
- Define a matrix of size K2 as:
T =
[0, 0, 0, …………., Ck]
[1, 0, 0, …………., Ck-1]
[0, 1, 0, …………., Ck-2]
[………………………..]
[………………………..]
[0, 0, 0, …………, 0, C2]
[0, 0, 0, …………, 0, C2]
[0, 0, 0, …………, 1, C1]
- Calculate the Nth power of matrix T[][] using binary exponentiation.
- Now, multiplying F[] with Nth power of T[][] gives:
FxTN = [FN, FN + 1, FN + 2, …………………….., FN + K]
- The first term of the resultant matrix F x TN is the required result.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; int mod = 1e9 + 7; // Declare T[][] as global matrix int T[2000][2000]; // Result matrix int result[2000][2000]; // Function to multiply two matrices void mul_2( int K) { // Create an auxiliary matrix to // store elements of the // multiplication matrix int temp[K + 1][K + 1]; memset (temp, 0, sizeof temp); // Iterate over range [0, K] for ( int i = 1; i <= K; i++) { for ( int j = 1; j <= K; j++) { for ( int k = 1; k <= K; k++) { // Update temp[i][j] temp[i][j] = (temp[i][j] + (T[i][k] * T[k][j]) % mod) % mod; } } } // Update the final matrix for ( int i = 1; i <= K; i++) { for ( int j = 1; j <= K; j++) { T[i][j] = temp[i][j]; } } } // Function to multiply two matrices void mul_1( int K) { // Create an auxiliary matrix to // store elements of the // multiplication matrix int temp[K + 1][K + 1]; memset (temp, 0, sizeof temp); // Iterate over range [0, K] for ( int i = 1; i <= K; i++) { for ( int j = 1; j <= K; j++) { for ( int k = 1; k <= K; k++) { // Update temp[i][j] temp[i][j] = (temp[i][j] + (result[i][k] * T[k][j]) % mod) % mod; } } } // Update the final matrix for ( int i = 1; i <= K; i++) { for ( int j = 1; j <= K; j++) { result[i][j] = temp[i][j]; } } } // Function to calculate matrix^n // using binary exponentaion void matrix_pow( int K, int n) { // Initialize result matrix // and unity matrix for ( int i = 1; i <= K; i++) { for ( int j = 1; j <= K; j++) { if (i == j) result[i][j] = 1; } } while (n > 0) { if (n % 2 == 1) mul_1(K); mul_2(K); n /= 2; } } // Function to calculate nth term // of general recurrence int NthTerm( int F[], int C[], int K, int n) { // Fill T[][] with appropriate value for ( int i = 1; i <= K; i++) T[i][K] = C[K - i]; for ( int i = 1; i <= K; i++) T[i + 1][i] = 1; // Function Call to calculate T^n matrix_pow(K, n); int answer = 0; // Calculate nth term as first // element of F*(T^n) for ( int i = 1; i <= K; i++) { answer += F[i - 1] * result[i][1]; } // Print the result cout << answer << endl; return 0; } // Driver Code int main() { // Given Initial terms int F[] = { 1, 2, 3 }; // Given coefficients int C[] = { 1, 1, 1 }; // Given K int K = 3; // Given N int N = 10; // Function Call NthTerm(F, C, K, N); return 0; } |
Java
// Java program for // the above approach import java.util.*; class GFG{ static int mod = ( int ) (1e9 + 7 ); // Declare T[][] as global matrix static int [][]T = new int [ 2000 ][ 2000 ]; // Result matrix static int [][]result = new int [ 2000 ][ 2000 ]; // Function to multiply two matrices static void mul_2( int K) { // Create an auxiliary matrix to // store elements of the // multiplication matrix int [][]temp = new int [K + 1 ][K + 1 ]; // Iterate over range [0, K] for ( int i = 1 ; i <= K; i++) { for ( int j = 1 ; j <= K; j++) { for ( int k = 1 ; k <= K; k++) { // Update temp[i][j] temp[i][j] = (temp[i][j] + (T[i][k] * T[k][j]) % mod) % mod; } } } // Update the final matrix for ( int i = 1 ; i <= K; i++) { for ( int j = 1 ; j <= K; j++) { T[i][j] = temp[i][j]; } } } // Function to multiply two matrices static void mul_1( int K) { // Create an auxiliary matrix to // store elements of the // multiplication matrix int [][]temp = new int [K + 1 ][K + 1 ]; // Iterate over range [0, K] for ( int i = 1 ; i <= K; i++) { for ( int j = 1 ; j <= K; j++) { for ( int k = 1 ; k <= K; k++) { // Update temp[i][j] temp[i][j] = (temp[i][j] + (result[i][k] * T[k][j]) % mod) % mod; } } } // Update the final matrix for ( int i = 1 ; i <= K; i++) { for ( int j = 1 ; j <= K; j++) { result[i][j] = temp[i][j]; } } } // Function to calculate matrix^n // using binary exponentaion static void matrix_pow( int K, int n) { // Initialize result matrix // and unity matrix for ( int i = 1 ; i <= K; i++) { for ( int j = 1 ; j <= K; j++) { if (i == j) result[i][j] = 1 ; } } while (n > 0 ) { if (n % 2 == 1 ) mul_1(K); mul_2(K); n /= 2 ; } } // Function to calculate nth term // of general recurrence static int NthTerm( int F[], int C[], int K, int n) { // Fill T[][] with appropriate value for ( int i = 1 ; i <= K; i++) T[i][K] = C[K - i]; for ( int i = 1 ; i <= K; i++) T[i + 1 ][i] = 1 ; // Function Call to calculate T^n matrix_pow(K, n); int answer = 0 ; // Calculate nth term as first // element of F * (T ^ n) for ( int i = 1 ; i <= K; i++) { answer += F[i - 1 ] * result[i][ 1 ]; } // Print the result System.out.print(answer + "\n" ); return 0 ; } // Driver Code public static void main(String[] args) { // Given Initial terms int F[] = { 1 , 2 , 3 }; // Given coefficients int C[] = { 1 , 1 , 1 }; // Given K int K = 3 ; // Given N int N = 10 ; // Function Call NthTerm(F, C, K, N); } } // This code is contributed by 29AjayKumar |
Python3
# Python3 program for # the above approach mod = 1e9 + 7 # Declare T[][] as global matrix T = [[ 0 for x in range ( 2000 )] for y in range ( 2000 )] # Result matrix result = [[ 0 for x in range ( 2000 )] for y in range ( 2000 )] # Function to multiply two matrices def mul_2(K): # Create an auxiliary matrix to # store elements of the # multiplication matrix temp = [[ 0 for x in range (K + 1 )] for y in range (K + 1 )] # Iterate over range [0, K] for i in range ( 1 , K + 1 ): for j in range ( 1 , K + 1 ): for k in range ( 1 , K + 1 ): # Update temp[i][j] temp[i][j] = ((temp[i][j] + (T[i][k] * T[k][j]) % mod) % mod) # Update the final matrix for i in range ( 1 , K + 1 ): for j in range ( 1 , K + 1 ): T[i][j] = temp[i][j] # Function to multiply two matrices def mul_1(K): # Create an auxiliary matrix to # store elements of the # multiplication matrix temp = [[ 0 for x in range (K + 1 )] for y in range (K + 1 )] # Iterate over range [0, K] for i in range ( 1 , K + 1 ): for j in range ( 1 , K + 1 ): for k in range ( 1 , K + 1 ): # Update temp[i][j] temp[i][j] = ((temp[i][j] + (result[i][k] * T[k][j]) % mod) % mod) # Update the final matrix for i in range ( 1 , K + 1 ): for j in range ( 1 , K + 1 ): result[i][j] = temp[i][j] # Function to calculate matrix^n # using binary exponentaion def matrix_pow(K, n): # Initialize result matrix # and unity matrix for i in range ( 1 , K + 1 ): for j in range ( 1 , K + 1 ): if (i = = j): result[i][j] = 1 while (n > 0 ): if (n % 2 = = 1 ): mul_1(K) mul_2(K) n / / = 2 # Function to calculate nth term # of general recurrence def NthTerm(F, C, K, n): # Fill T[][] with appropriate value for i in range ( 1 , K + 1 ): T[i][K] = C[K - i] for i in range ( 1 , K + 1 ): T[i + 1 ][i] = 1 # Function Call to calculate T^n matrix_pow(K, n) answer = 0 # Calculate nth term as first # element of F*(T^n) for i in range ( 1 , K + 1 ): answer + = F[i - 1 ] * result[i][ 1 ] # Print the result print ( int (answer)) # Driver Code if __name__ = = "__main__" : # Given Initial terms F = [ 1 , 2 , 3 ] # Given coefficients C = [ 1 , 1 , 1 ] # Given K K = 3 # Given N N = 10 # Function Call NthTerm(F, C, K, N) # This code is contributed by Chitranayal |
C#
// C# program for // the above approach using System; class GFG{ static int mod = ( int ) (1e9 + 7); // Declare T[,] as global matrix static int [,]T = new int [2000, 2000]; // Result matrix static int [,]result = new int [2000, 2000]; // Function to multiply two matrices static void mul_2( int K) { // Create an auxiliary matrix to // store elements of the // multiplication matrix int [,]temp = new int [K + 1, K + 1]; // Iterate over range [0, K] for ( int i = 1; i <= K; i++) { for ( int j = 1; j <= K; j++) { for ( int k = 1; k <= K; k++) { // Update temp[i,j] temp[i, j] = (temp[i, j] + (T[i, k] * T[k, j]) % mod) % mod; } } } // Update the readonly matrix for ( int i = 1; i <= K; i++) { for ( int j = 1; j <= K; j++) { T[i, j] = temp[i, j]; } } } // Function to multiply two matrices static void mul_1( int K) { // Create an auxiliary matrix to // store elements of the // multiplication matrix int [,]temp = new int [K + 1, K + 1]; // Iterate over range [0, K] for ( int i = 1; i <= K; i++) { for ( int j = 1; j <= K; j++) { for ( int k = 1; k <= K; k++) { // Update temp[i,j] temp[i,j] = (temp[i, j] + (result[i, k] * T[k, j]) % mod) % mod; } } } // Update the readonly matrix for ( int i = 1; i <= K; i++) { for ( int j = 1; j <= K; j++) { result[i, j] = temp[i, j]; } } } // Function to calculate matrix^n // using binary exponentaion static void matrix_pow( int K, int n) { // Initialize result matrix // and unity matrix for ( int i = 1; i <= K; i++) { for ( int j = 1; j <= K; j++) { if (i == j) result[i, j] = 1; } } while (n > 0) { if (n % 2 == 1) mul_1(K); mul_2(K); n /= 2; } } // Function to calculate nth term // of general recurrence static int NthTerm( int []F, int []C, int K, int n) { // Fill T[,] with appropriate value for ( int i = 1; i <= K; i++) T[i, K] = C[K - i]; for ( int i = 1; i <= K; i++) T[i + 1, i] = 1; // Function Call to calculate T^n matrix_pow(K, n); int answer = 0; // Calculate nth term as first // element of F * (T ^ n) for ( int i = 1; i <= K; i++) { answer += F[i - 1] * result[i, 1]; } // Print the result Console.Write(answer + "\n" ); return 0; } // Driver Code public static void Main(String[] args) { // Given Initial terms int []F = {1, 2, 3}; // Given coefficients int []C = {1, 1, 1}; // Given K int K = 3; // Given N int N = 10; // Function Call NthTerm(F, C, K, N); } } // This code is contributed by Rajput-Ji |
Javascript
<script> // Javascript program for the above approach let mod = (1e9 + 7); // Declare T[][] as global matrix let T = new Array(2000); // Result matrix let result = new Array(2000); for (let i = 0; i < 2000; i++) { T[i] = new Array(2000); result[i] = new Array(2000); for (let j = 0; j < 2000; j++) { T[i][j] = 0; result[i][j] = 0; } } // Function to multiply two matrices function mul_2(K) { // Create an auxiliary matrix to // store elements of the // multiplication matrix let temp = new Array(K + 1); for (let i = 0; i <= K; i++) { temp[i] = new Array(K + 1); for (let j = 0; j <= K; j++) { temp[i][j] = 0; } } // Iterate over range [0, K] for (let i = 1; i <= K; i++) { for (let j = 1; j <= K; j++) { for (let k = 1; k <= K; k++) { // Update temp[i][j] temp[i][j] = (temp[i][j] + (T[i][k] * T[k][j]) % mod) % mod; } } } // Update the final matrix for (let i = 1; i <= K; i++) { for (let j = 1; j <= K; j++) { T[i][j] = temp[i][j]; } } } // Function to multiply two matrices function mul_1(K) { // Create an auxiliary matrix to // store elements of the // multiplication matrix let temp = new Array(K + 1); for (let i = 0; i <= K; i++) { temp[i] = new Array(K + 1); for (let j = 0; j <= K; j++) { temp[i][j] = 0; } } // Iterate over range [0, K] for (let i = 1; i <= K; i++) { for (let j = 1; j <= K; j++) { for (let k = 1; k <= K; k++) { // Update temp[i][j] temp[i][j] = (temp[i][j] + (result[i][k] * T[k][j]) % mod) % mod; } } } // Update the final matrix for (let i = 1; i <= K; i++) { for (let j = 1; j <= K; j++) { result[i][j] = temp[i][j]; } } } // Function to calculate matrix^n // using binary exponentaion function matrix_pow(K, n) { // Initialize result matrix // and unity matrix for (let i = 1; i <= K; i++) { for (let j = 1; j <= K; j++) { if (i == j) result[i][j] = 1; } } while (n > 0) { if (n % 2 == 1) mul_1(K); mul_2(K); n = parseInt(n / 2, 10); } } // Function to calculate nth term // of general recurrence function NthTerm(F, C, K, n) { // Fill T[][] with appropriate value for (let i = 1; i <= K; i++) T[i][K] = C[K - i]; for (let i = 1; i <= K; i++) T[i + 1][i] = 1; // Function Call to calculate T^n matrix_pow(K, n); let answer = 0; // Calculate nth term as first // element of F * (T ^ n) for (let i = 1; i <= K; i++) { answer += F[i - 1] * result[i][1]; } // Print the result document.write(answer + "</br>" ); return 0; } // Given Initial terms let F = [1, 2, 3]; // Given coefficients let C = [1, 1, 1]; // Given K let K = 3; // Given N let N = 10; // Function Call NthTerm(F, C, K, N); // This code is contributed by mukesh07. </script> |
423
Time Complexity: O(K3log(N))
Auxiliary Space: O(K*K)
Please Login to comment...