📌  相关文章
📜  给定递归关系的第N个项,每个项等于前K个项的乘积

📅  最后修改于: 2021-04-22 00:40:42             🧑  作者: Mango

给定两个正整数NK,以及由K个正整数组成的数组F [] 。所述N个递归关系的术语由下式给出:

任务是找到给定递归关系的N。由于第N项可能非常大,请打印第N项以10 9 + 7为模。

例子:

天真的方法:想法是使用递归关系生成给定序列的所有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)