Nth term of given recurrence relation having each term equal to the product of previous K terms
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.
Below is the implementation of the above approach:
C++
// 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
// 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
# 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#
// 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 |
Javascript
<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++
// 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
// 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
# 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#
// 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 |
Javascript
<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)