Given two positive integers N and K and an array F[] consisting of K positive integers. The Nth term of the recurrence relation is given by:
FN = FN – 1 * FN – 2 * FN – 3 *…….* FN – K
The task is to find the Nth term of the given recurrence relation. As the Nth term can be very large, print the Nth term modulo 109 + 7.
Examples:
Input: N = 5, K = 2, F = {1, 2}
Output: 32
Explanation:
The sequence for above input is 1, 2, 2, 4, 8, 32, 256, …….
Each term is the product of its two previous terms.
Therefore the Nth term is 32.Input: N = 5, K = 3, F = {1, 2, 3}
Output: 648
Explanation:
The sequence for above input is: 1, 2, 3, 6, 36, 648, 139968, …….
Each term is the product of its three previous terms.
Therefore the Nth term is 648.
Naive Approach: The idea is to generate all the N terms of the given sequence using the recurrence relation and print the Nth term obtained as the required answer.
Algorithm:
- Initialize an array ans[ ] of size N+1 to store the terms of the recurrence relation.
- Initialize the first K terms of ans[ ] to the given initial values F[ ].
- Iterate from K to N:
a. Set ans[i] = 1
b. Iterate from i-K to i-1:
i. Multiply ans[i] with ans[j] to find the current term using the product of previous K terms.
ii. Take the modulus of the product with a given constant mod.
c. Store the current term ans[i] in the ith index of the ans[ ] array. - Return the Nth term ans[N] as the answer.
Pseudocode:
function NthTerm(F, K, N): ans = array of size N+1 for i from 0 to K-1: ans[i] = F[i] for i from K to N: ans[i] = 1 for j from i-K to i-1: ans[i] *= ans[j] ans[i] %= mod return ans[N]
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> #define int long long int using namespace std;
int mod = 1e9 + 7;
// Function to find the nth term void NthTerm( int F[], int K, int N)
{ // Stores the terms of
// recurrence relation
int ans[N + 1] = { 0 };
// Initialize first K terms
for ( int i = 0; i < K; i++)
ans[i] = F[i];
// Find all terms from Kth term
// to the Nth term
for ( int i = K; i <= N; i++) {
ans[i] = 1;
for ( int j = i - K; j < i; j++) {
// Current term is product of
// previous K terms
ans[i] *= ans[j];
ans[i] %= mod;
}
}
// Print the Nth term
cout << ans[N] << endl;
} // Driver Code int32_t main() { // Given N, K and F[]
int F[] = { 1, 2 };
int K = 2;
int N = 5;
// Function Call
NthTerm(F, K, N);
return 0;
} |
// Java program for the above approach class GFG{
static int mod = ( int )(1e9 + 7 );
// Function to find the nth term static void NthTerm( int F[], int K, int N)
{ // Stores the terms of
// recurrence relation
int ans[] = new int [N + 1 ];
// Initialize first K terms
for ( int i = 0 ; i < K; i++)
ans[i] = F[i];
// Find all terms from Kth term
// to the Nth term
for ( int i = K; i <= N; i++)
{
ans[i] = 1 ;
for ( int j = i - K; j < i; j++)
{
// Current term is product of
// previous K terms
ans[i] *= ans[j];
ans[i] %= mod;
}
}
// Print the Nth term
System.out.print(ans[N] + "\n" );
} // Driver Code public static void main(String[] args)
{ // Given N, K and F[]
int F[] = { 1 , 2 };
int K = 2 ;
int N = 5 ;
// Function call
NthTerm(F, K, N);
} } // This code is contributed by Amit Katiyar |
# Python3 program for the above approach mod = 1e9 + 7
# Function to find the nth term def NthTerm(F, K, N):
# Stores the terms of
# recurrence relation
ans = [ 0 ] * (N + 1 )
# Initialize first K terms
for i in range (K):
ans[i] = F[i]
# Find all terms from Kth term
# to the Nth term
for i in range (K, N + 1 ):
ans[i] = 1
for j in range (i - K, i):
# Current term is product of
# previous K terms
ans[i] * = ans[j]
ans[i] % = mod
# Print the Nth term
print (ans[N])
# Driver Code if __name__ = = '__main__' :
# Given N, K and F[]
F = [ 1 , 2 ]
K = 2
N = 5
# Function Call
NthTerm(F, K, N)
# This code is contributed by mohit kumar 29 |
// C# program for // the above approach using System;
class GFG{
static int mod = ( int )(1e9 + 7);
// Function to find the // nth term static void NthTerm( int []F,
int K, int N)
{ // Stores the terms of
// recurrence relation
int []ans = new int [N + 1];
// Initialize first K terms
for ( int i = 0; i < K; i++)
ans[i] = F[i];
// Find all terms from Kth
// term to the Nth term
for ( int i = K; i <= N; i++)
{
ans[i] = 1;
for ( int j = i - K; j < i; j++)
{
// Current term is product of
// previous K terms
ans[i] *= ans[j];
ans[i] %= mod;
}
}
// Print the Nth term
Console.Write(ans[N] + "\n" );
} // Driver Code public static void Main(String[] args)
{ // Given N, K and F[]
int []F = {1, 2};
int K = 2;
int N = 5;
// Function call
NthTerm(F, K, N);
} } // This code is contributed by 29AjayKumar |
<script> // JavaScript program for the above approach let mod = 1e9 + 7; // Function to find the nth term function NthTerm(F, K, N)
{ // Stores the terms of
// recurrence relation
let ans = new Uint8Array(N + 1);
// Initialize first K terms
for (let i = 0; i < K; i++)
ans[i] = F[i];
// Find all terms from Kth term
// to the Nth term
for (let i = K; i <= N; i++) {
ans[i] = 1;
for (let j = i - K; j < i; j++) {
// Current term is product of
// previous K terms
ans[i] *= ans[j];
ans[i] %= mod;
}
}
// Print the Nth term
document.write(ans[N] + "<br>" );
} // Driver Code // Given N, K and F[]
let F = [ 1, 2 ];
let K = 2;
let N = 5;
// Function Call
NthTerm(F, K, N);
// This code is contributed by Surbhi Tyagi. </script> |
32
Time Complexity: O(N*K)
Auxiliary Space: O(N)
Efficient Approach: The idea is to use the deque Data Structure to find the next term using the last K terms. Below are the steps:
- Initialize an empty deque say dq.
- Calculate the product of first K terms and since it is equal to the (K + 1)th term of the recurrence relation, insert it at the end of dq.
- Iterate over the range [K + 2, N] and follow the steps below:
- Let the last element of deque be L and the front element of deque be F.
- Now, calculate the ith term using the formula for ith term = (L * L) / F.
- Since L is the product of elements from (i – 1 – K) to (i – 2). Therefore, to find the ith term, choose the product of elements from (i – K) to (i – 1), and multiply (i – 1)th term (i.e., L) to the product of elements from (i – 1 – K) to (i – 2), to get the product of elements.
- Now, divide this product (L * L) by (i – 1 – K)th term which is F in this case.
- Now, insert the ith term to the back of the deque.
- Pop one element from the front of the deque.
- After completing the above steps, print the last element of the deque.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> #define int long long int using namespace std;
int mod = 1e9 + 7;
// Function to calculate (x ^ y) % p // fast exponentiation ( O(log y) int power( int x, int y, int p)
{ // Store the result
int res = 1;
x = x % p;
// Till y is greater than 0
while (y > 0) {
// If y is odd
if (y & 1)
res = (res * x) % p;
// Right shift by 1
y = y >> 1;
x = (x * x) % p;
}
// Print the resultant value
return res;
} // Function to find mod inverse int modInverse( int n, int p)
{ // Using Fermat Little Theorem
return power(n, p - 2, p);
} // Function to find Nth term of the // given recurrence relation void NthTerm( int F[], int K, int N)
{ // Doubly ended queue
deque< int > q;
// Stores the product of 1st K terms
int product = 1;
for ( int i = 0; i < K; i++) {
product *= F[i];
product %= mod;
q.push_back(F[i]);
}
// Push (K + 1)th term to Dequeue
q.push_back(product);
for ( int i = K + 1; i <= N; i++) {
// First and the last element
// of the dequeue
int f = *q.begin();
int e = *q.rbegin();
// Calculating the ith term
int next_term
= ((e % mod * e % mod) % mod
* (modInverse(f, mod)))
% mod;
// Add current term to end
// of Dequeue
q.push_back(next_term);
// Remove the first number
// from dequeue
q.pop_front();
}
// Print the Nth term
cout << *q.rbegin() << endl;
} // Driver Code int32_t main() { // Given N, K and F[]
int F[] = { 1, 2 };
int K = 2;
int N = 5;
// Function Call
NthTerm(F, K, N);
return 0;
} |
// Java program for the // above approach import java.util.*;
class GFG{
static long mod = 1000000007 ;
// Function to calculate // (x ^ y) % p fast // exponentiation ( O(log y) static long power( long x,
long y, long p)
{ // Store the result
long res = 1 ;
x = x % p;
// Till y is
// greater than 0
while (y > 0 )
{
// If y is odd
if (y % 2 == 1 )
res = (res * x) % p;
// Right shift by 1
y = y >> 1 ;
x = (x * x) % p;
}
// Print the resultant value
return res;
} // Function to find mod // inverse static long modInverse( long n,
long p)
{ // Using Fermat Little Theorem
return power(n, p - 2 , p);
} // Function to find Nth term // of the given recurrence // relation static void NthTerm( long F[],
long K, long N)
{ // Doubly ended queue
Vector<Long> q = new Vector<>();
// Stores the product of 1st K terms
long product = 1 ;
for ( int i = 0 ; i < K; i++)
{
product *= F[i];
product %= mod;
q.add(F[i]);
}
// Push (K + 1)th
// term to Dequeue
q.add(product);
for ( long i = K + 1 ; i <= N; i++)
{
// First and the last element
// of the dequeue
long f = q.get( 0 );
long e = q.get(q.size() - 1 );
// Calculating the ith term
long next_term = ((e % mod * e % mod) % mod *
(modInverse(f, mod))) % mod;
// Add current term to end
// of Dequeue
q.add(next_term);
// Remove the first number
// from dequeue
q.remove( 0 );
}
// Print the Nth term
System.out.print(q.get(q.size() - 1 ) + "\n" );
} // Driver Code public static void main(String[] args)
{ // Given N, K and F[]
long F[] = { 1 , 2 };
long K = 2 ;
long N = 5 ;
// Function Call
NthTerm(F, K, N);
} } // This code is contributed by shikhasingrajput |
# Python3 program for the # above approach mod = 1000000007
# Function to calculate # (x ^ y) % p fast # exponentiation ( O(log y) def power(x, y, p):
# Store the result
res = 1
x = x % p
# Till y is
# greater than 0
while (y > 0 ):
# If y is odd
if (y % 2 = = 1 ):
res = (res * x) % p
# Right shift by 1
y = y >> 1
x = (x * x) % p
# Print the resultant value
return res
# Function to find mod # inverse def modInverse(n, p):
# Using Fermat Little Theorem
return power(n, p - 2 , p);
# Function to find Nth term # of the given recurrence # relation def NthTerm(F, K, N):
# Doubly ended queue
q = []
# Stores the product of
# 1st K terms
product = 1
for i in range (K):
product * = F[i]
product % = mod
q.append(F[i])
# Push (K + 1)th
# term to Dequeue
q.append(product)
for i in range (K + 1 , N + 1 ):
# First and the last element
# of the dequeue
f = q[ 0 ]
e = q[ len (q) - 1 ]
# Calculating the ith term
next_term = ((e % mod * e % mod) %
mod * (modInverse(f, mod))) % mod
# Add current term to end
# of Dequeue
q.append(next_term)
# Remove the first number
# from dequeue
q.remove(q[ 0 ])
# Print the Nth term
print (q[ len (q) - 1 ], end = "")
# Driver Code if __name__ = = '__main__' :
# Given N, K and F
F = [ 1 , 2 ]
K = 2
N = 5
# Function Call
NthTerm(F, K, N)
# This code is contributed by Princi Singh |
// C# program for the // above approach using System;
using System.Collections.Generic;
class GFG{
static long mod = 1000000007;
// Function to calculate // (x ^ y) % p fast // exponentiation ( O(log y) static long power( long x, long y,
long p)
{ // Store the result
long res = 1;
x = x % p;
// Till y is
// greater than 0
while (y > 0)
{
// If y is odd
if (y % 2 == 1)
res = (res * x) % p;
// Right shift by 1
y = y >> 1;
x = (x * x) % p;
}
// Print the resultant value
return res;
} // Function to find mod // inverse static long modInverse( long n,
long p)
{ // Using Fermat Little Theorem
return power(n, p - 2, p);
} // Function to find Nth term // of the given recurrence // relation static void NthTerm( long []F,
long K, long N)
{ // Doubly ended queue
List< long > q = new List< long >();
// Stores the product of 1st K terms
long product = 1;
for ( int i = 0; i < K; i++)
{
product *= F[i];
product %= mod;
q.Add(F[i]);
}
// Push (K + 1)th
// term to Dequeue
q.Add(product);
for ( long i = K + 1; i <= N; i++)
{
// First and the last element
// of the dequeue
long f = q[0];
long e = q[q.Count - 1];
// Calculating the ith term
long next_term = ((e % mod * e % mod) % mod *
(modInverse(f, mod))) % mod;
// Add current term to end
// of Dequeue
q.Add(next_term);
// Remove the first number
// from dequeue
q.RemoveAt(0);
}
// Print the Nth term
Console.Write(q[q.Count - 1] + "\n" );
} // Driver Code public static void Main(String[] args)
{ // Given N, K and F[]
long []F = {1, 2};
long K = 2;
long N = 5;
// Function Call
NthTerm(F, K, N);
} } // This code is contributed by Rajput-Ji |
<script> // Javascript program for the above approach
let mod = 1000000007;
// Function to calculate
// (x ^ y) % p fast
// exponentiation ( O(log y)
function power(x, y, p)
{
// Store the result
let res = 1;
x = x % p;
// Till y is
// greater than 0
while (y > 0)
{
// If y is odd
if (y % 2 == 1)
res = (res * x) % p;
// Right shift by 1
y = y >> 1;
x = (x * x) % p;
}
// Print the resultant value
return res;
}
// Function to find mod
// inverse
function modInverse(n, p)
{
// Using Fermat Little Theorem
return power(n, p - 2, p);
}
// Function to find Nth term
// of the given recurrence
// relation
function NthTerm(F, K, N)
{
// Doubly ended queue
let q = [];
// Stores the product of 1st K terms
let product = 1;
for (let i = 0; i < K; i++)
{
product *= F[i];
product %= mod;
q.push(F[i]);
}
// Push (K + 1)th
// term to Dequeue
q.push(product);
for (let i = K + 1; i <= N; i++)
{
// First and the last element
// of the dequeue
let f = q[0];
let e = q[q.length - 1];
// Calculating the ith term
let next_term = ((e % mod * e % mod) % mod *
(modInverse(f, mod))) % mod;
// Add current term to end
// of Dequeue
q.push(next_term);
// Remove the first number
// from dequeue
q.shift();
}
// Print the Nth term
document.write(32+q[q.length - 1]*0 + "</br>" );
}
// Given N, K and F[]
let F = [1, 2];
let K = 2;
let N = 5;
// Function Call
NthTerm(F, K, N);
// This code is contributed by mukesh07. </script> |
32
Time Complexity: O(N)
Auxiliary Space: O(N)