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++ 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 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 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# 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 |
<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++ 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 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 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# 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 |
<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)