给定两个正整数N和K,以及由K个正整数组成的数组F [] 。所述N个递归关系的第术语由下式给出:
FN = FN – 1 * FN – 2 * FN – 3 *…….* FN – K
任务是找到给定递归关系的第N个项。由于第N个项可能非常大,请打印第N个项以10 9 + 7为模。
例子:
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.
天真的方法:想法是使用递归关系生成给定序列的所有N个术语,并打印获得的N个术语作为所需答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
#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
// reccurrence 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
// reccurrence 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
# reccurrence 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
// reccurrence 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
C++
// C++ program for the above approach
#include
#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 Theorm
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 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 Theorm
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 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 Theorm
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 Theorm
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 q = new List();
// 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
32
时间复杂度: O(N * K)
辅助空间: O(N)
高效的方法:想法是使用双端队列数据结构使用最后K个术语来查找下一个术语。步骤如下:
- 初始化一个空的双端队列,说dq 。
- 计算前K个项的乘积,由于它等于递归关系的第(K +1)个项,因此请将其插入dq的末尾。
- 在[K + 2,N]范围内进行迭代,然后执行以下步骤:
- 令双端队列的最后一个元素为L ,双端队列的前一个元素为F。
- 现在,计算第i使用用于第i项的公式=(L * L)/ F个术语。
- 因为L是元素从(i – 1 – K)到(i – 2)的乘积。因此,要找到第i个项,请选择(i – K)到(i – 1)的元素乘积,然后将第(i – 1)个项(即L )与(i – K)的元素乘积相乘。 1 – K)到(i – 2) ,以获得元素的乘积。
- ( – 1 – K i)个术语,其是F在这种情况下,现在,通过划分该产品的(L * L)。
- 现在,插入第i项的双端队列的后面。
- 从双端队列的前面弹出一个元素。
- 完成上述步骤后,打印双端队列的最后一个元素。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
#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 Theorm
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 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 Theorm
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 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 Theorm
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 Theorm
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 q = new List();
// 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
32
时间复杂度: O(N)
辅助空间: O(N)