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++
#include <bits/stdc++.h>
#define int long long int
using namespace std;
int mod = 1e9 + 7;
void NthTerm( int F[], int K, int N)
{
int ans[N + 1] = { 0 };
for ( int i = 0; i < K; i++)
ans[i] = F[i];
for ( int i = K; i <= N; i++) {
ans[i] = 1;
for ( int j = i - K; j < i; j++) {
ans[i] *= ans[j];
ans[i] %= mod;
}
}
cout << ans[N] << endl;
}
int32_t main()
{
int F[] = { 1, 2 };
int K = 2;
int N = 5;
NthTerm(F, K, N);
return 0;
}
|
Java
class GFG{
static int mod = ( int )(1e9 + 7 );
static void NthTerm( int F[], int K, int N)
{
int ans[] = new int [N + 1 ];
for ( int i = 0 ; i < K; i++)
ans[i] = F[i];
for ( int i = K; i <= N; i++)
{
ans[i] = 1 ;
for ( int j = i - K; j < i; j++)
{
ans[i] *= ans[j];
ans[i] %= mod;
}
}
System.out.print(ans[N] + "\n" );
}
public static void main(String[] args)
{
int F[] = { 1 , 2 };
int K = 2 ;
int N = 5 ;
NthTerm(F, K, N);
}
}
|
Python3
mod = 1e9 + 7
def NthTerm(F, K, N):
ans = [ 0 ] * (N + 1 )
for i in range (K):
ans[i] = F[i]
for i in range (K, N + 1 ):
ans[i] = 1
for j in range (i - K, i):
ans[i] * = ans[j]
ans[i] % = mod
print (ans[N])
if __name__ = = '__main__' :
F = [ 1 , 2 ]
K = 2
N = 5
NthTerm(F, K, N)
|
C#
using System;
class GFG{
static int mod = ( int )(1e9 + 7);
static void NthTerm( int []F,
int K, int N)
{
int []ans = new int [N + 1];
for ( int i = 0; i < K; i++)
ans[i] = F[i];
for ( int i = K; i <= N; i++)
{
ans[i] = 1;
for ( int j = i - K; j < i; j++)
{
ans[i] *= ans[j];
ans[i] %= mod;
}
}
Console.Write(ans[N] + "\n" );
}
public static void Main(String[] args)
{
int []F = {1, 2};
int K = 2;
int N = 5;
NthTerm(F, K, N);
}
}
|
Javascript
<script>
let mod = 1e9 + 7;
function NthTerm(F, K, N)
{
let ans = new Uint8Array(N + 1);
for (let i = 0; i < K; i++)
ans[i] = F[i];
for (let i = K; i <= N; i++) {
ans[i] = 1;
for (let j = i - K; j < i; j++) {
ans[i] *= ans[j];
ans[i] %= mod;
}
}
document.write(ans[N] + "<br>" );
}
let F = [ 1, 2 ];
let K = 2;
let N = 5;
NthTerm(F, K, N);
</script>
|
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++
#include <bits/stdc++.h>
#define int long long int
using namespace std;
int mod = 1e9 + 7;
int power( int x, int y, int p)
{
int res = 1;
x = x % p;
while (y > 0) {
if (y & 1)
res = (res * x) % p;
y = y >> 1;
x = (x * x) % p;
}
return res;
}
int modInverse( int n, int p)
{
return power(n, p - 2, p);
}
void NthTerm( int F[], int K, int N)
{
deque< int > q;
int product = 1;
for ( int i = 0; i < K; i++) {
product *= F[i];
product %= mod;
q.push_back(F[i]);
}
q.push_back(product);
for ( int i = K + 1; i <= N; i++) {
int f = *q.begin();
int e = *q.rbegin();
int next_term
= ((e % mod * e % mod) % mod
* (modInverse(f, mod)))
% mod;
q.push_back(next_term);
q.pop_front();
}
cout << *q.rbegin() << endl;
}
int32_t main()
{
int F[] = { 1, 2 };
int K = 2;
int N = 5;
NthTerm(F, K, N);
return 0;
}
|
Java
import java.util.*;
class GFG{
static long mod = 1000000007 ;
static long power( long x,
long y, long p)
{
long res = 1 ;
x = x % p;
while (y > 0 )
{
if (y % 2 == 1 )
res = (res * x) % p;
y = y >> 1 ;
x = (x * x) % p;
}
return res;
}
static long modInverse( long n,
long p)
{
return power(n, p - 2 , p);
}
static void NthTerm( long F[],
long K, long N)
{
Vector<Long> q = new Vector<>();
long product = 1 ;
for ( int i = 0 ; i < K; i++)
{
product *= F[i];
product %= mod;
q.add(F[i]);
}
q.add(product);
for ( long i = K + 1 ; i <= N; i++)
{
long f = q.get( 0 );
long e = q.get(q.size() - 1 );
long next_term = ((e % mod * e % mod) % mod *
(modInverse(f, mod))) % mod;
q.add(next_term);
q.remove( 0 );
}
System.out.print(q.get(q.size() - 1 ) + "\n" );
}
public static void main(String[] args)
{
long F[] = { 1 , 2 };
long K = 2 ;
long N = 5 ;
NthTerm(F, K, N);
}
}
|
Python3
mod = 1000000007
def power(x, y, p):
res = 1
x = x % p
while (y > 0 ):
if (y % 2 = = 1 ):
res = (res * x) % p
y = y >> 1
x = (x * x) % p
return res
def modInverse(n, p):
return power(n, p - 2 , p);
def NthTerm(F, K, N):
q = []
product = 1
for i in range (K):
product * = F[i]
product % = mod
q.append(F[i])
q.append(product)
for i in range (K + 1 , N + 1 ):
f = q[ 0 ]
e = q[ len (q) - 1 ]
next_term = ((e % mod * e % mod) %
mod * (modInverse(f, mod))) % mod
q.append(next_term)
q.remove(q[ 0 ])
print (q[ len (q) - 1 ], end = "")
if __name__ = = '__main__' :
F = [ 1 , 2 ]
K = 2
N = 5
NthTerm(F, K, N)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static long mod = 1000000007;
static long power( long x, long y,
long p)
{
long res = 1;
x = x % p;
while (y > 0)
{
if (y % 2 == 1)
res = (res * x) % p;
y = y >> 1;
x = (x * x) % p;
}
return res;
}
static long modInverse( long n,
long p)
{
return power(n, p - 2, p);
}
static void NthTerm( long []F,
long K, long N)
{
List< long > q = new List< long >();
long product = 1;
for ( int i = 0; i < K; i++)
{
product *= F[i];
product %= mod;
q.Add(F[i]);
}
q.Add(product);
for ( long i = K + 1; i <= N; i++)
{
long f = q[0];
long e = q[q.Count - 1];
long next_term = ((e % mod * e % mod) % mod *
(modInverse(f, mod))) % mod;
q.Add(next_term);
q.RemoveAt(0);
}
Console.Write(q[q.Count - 1] + "\n" );
}
public static void Main(String[] args)
{
long []F = {1, 2};
long K = 2;
long N = 5;
NthTerm(F, K, N);
}
}
|
Javascript
<script>
let mod = 1000000007;
function power(x, y, p)
{
let res = 1;
x = x % p;
while (y > 0)
{
if (y % 2 == 1)
res = (res * x) % p;
y = y >> 1;
x = (x * x) % p;
}
return res;
}
function modInverse(n, p)
{
return power(n, p - 2, p);
}
function NthTerm(F, K, N)
{
let q = [];
let product = 1;
for (let i = 0; i < K; i++)
{
product *= F[i];
product %= mod;
q.push(F[i]);
}
q.push(product);
for (let i = K + 1; i <= N; i++)
{
let f = q[0];
let e = q[q.length - 1];
let next_term = ((e % mod * e % mod) % mod *
(modInverse(f, mod))) % mod;
q.push(next_term);
q.shift();
}
document.write(32+q[q.length - 1]*0 + "</br>" );
}
let F = [1, 2];
let K = 2;
let N = 5;
NthTerm(F, K, N);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
24 Apr, 2023
Like Article
Save Article