Open In App

Products of ranges in an array

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array A[] of size N. Solve Q queries. Find the product in the range [L, R] under modulo P ( P is Prime). 

Examples:  

Input : A[] = {1, 2, 3, 4, 5, 6} 
          L = 2, R = 5, P = 229
Output : 120

Input : A[] = {1, 2, 3, 4, 5, 6},
         L = 2, R = 5, P = 113
Output : 7 

Brute Force: For each of the queries, traverse each element in the range [L, R] and calculate the product under modulo P. This will answer each query in O(N).  

Implementation:

C++




// Product in range
// Queries in O(N)
#include <bits/stdc++.h>
using namespace std;
 
// Function to calculate
// Product in the given range.
int calculateProduct(int A[], int L,
                     int R, int P)
{
    // As our array is 0 based
    // as and L and R are given
    // as 1 based index.
    L = L - 1;
    R = R - 1;
 
    int ans = 1;
    for (int i = L; i <= R; i++)
    {
        ans = ans * A[i];
        ans = ans % P;
    }
 
    return ans;
}
 
// Driver code
int main()
{
    int A[] = { 1, 2, 3, 4, 5, 6 };
    int P = 229;
    int L = 2, R = 5;
    cout << calculateProduct(A, L, R, P)
         << endl;
 
    L = 1, R = 3;
    cout << calculateProduct(A, L, R, P)
         << endl;
 
    return 0;
}


Java




// Product in range Queries in O(N)
import java.io.*;
 
class GFG
{
     
    // Function to calculate
    // Product in the given range.
    static int calculateProduct(int []A, int L,
                                int R, int P)
    {
         
        // As our array is 0 based as
        // and L and R are given as 1
        // based index.
        L = L - 1;
        R = R - 1;
     
        int ans = 1;
        for (int i = L; i <= R; i++)
        {
            ans = ans * A[i];
            ans = ans % P;
        }
     
        return ans;
    }
     
    // Driver code
    static public void main (String[] args)
    {
        int []A = { 1, 2, 3, 4, 5, 6 };
        int P = 229;
        int L = 2, R = 5;
        System.out.println(
            calculateProduct(A, L, R, P));
     
        L = 1;
        R = 3;
        System.out.println(
            calculateProduct(A, L, R, P));
    }
}
 
// This code is contributed by vt_m.


Python3




# Python3 program to find
# Product in range Queries in O(N)
 
# Function to calculate Product
# in the given range.
def calculateProduct (A, L, R, P):
 
    # As our array is 0 based 
    # and L and R are given as
    # 1 based index.
    L = L - 1
    R = R - 1
    ans = 1
    for i in range(R + 1):
        ans = ans * A[i]
        ans = ans % P
    return ans
     
# Driver code
A = [ 1, 2, 3, 4, 5, 6 ]
P = 229
L = 2
R = 5
print (calculateProduct(A, L, R, P))
L = 1
R = 3
print (calculateProduct(A, L, R, P))
 
# This code is contributed
# by "Abhishek Sharma 44"


C#




// Product in range Queries in O(N)
using System;
 
class GFG
{
     
    // Function to calculate
    // Product in the given range.
    static int calculateProduct(int []A, int L,    
                                int R, int P)
    {
         
        // As our array is 0 based
        // as and L and R are given
        // as 1 based index.
        L = L - 1;
        R = R - 1;
     
        int ans = 1;
        for (int i = L; i <= R; i++)
        {
            ans = ans * A[i];
            ans = ans % P;
        }
     
        return ans;
    }
     
    // Driver code
    static public void Main ()
    {
        int []A = { 1, 2, 3, 4, 5, 6 };
        int P = 229;
        int L = 2, R = 5;
        Console.WriteLine(
            calculateProduct(A, L, R, P));
     
        L = 1;
        R = 3;
        Console.WriteLine(
            calculateProduct(A, L, R, P));
    }
}
 
// This code is contributed by vt_m.


PHP




<?php
// Product in range Queries in O(N)
 
// Function to calculate
// Product in the given range.
function calculateProduct($A, $L,
                          $R, $P)
{
    // As our array is 0 based as
    // and L and R are given as 1
    // based index.
    $L = $L - 1;
    $R = $R - 1;
 
    $ans = 1;
    for ($i = $L; $i <= $R; $i++)
    {
        $ans = $ans * $A[$i];
        $ans = $ans % $P;
    }
 
    return $ans;
}
 
// Driver code
$A = array( 1, 2, 3, 4, 5, 6 );
$P = 229;
$L = 2; $R = 5;
echo calculateProduct($A, $L, $R, $P),"\n" ;
 
$L = 1; $R = 3;
echo calculateProduct($A, $L, $R, $P),"\n" ;
 
// This code is contributed by ajit.
?>


Javascript




<script>
     
    // Product in range Queries in O(N)
     
    // Function to calculate
    // Product in the given range.
    function calculateProduct(A, L, R, P)
    {
           
        // As our array is 0 based
        // as and L and R are given
        // as 1 based index.
        L = L - 1;
        R = R - 1;
       
        let ans = 1;
        for (let i = L; i <= R; i++)
        {
            ans = ans * A[i];
            ans = ans % P;
        }
       
        return ans;
    }
     
    let A = [ 1, 2, 3, 4, 5, 6 ];
    let P = 229;
    let L = 2, R = 5;
    document.write(calculateProduct(A, L, R, P) + "</br>");
 
    L = 1;
    R = 3;
    document.write(calculateProduct(A, L, R, P) + "</br>");
         
</script>


Output

120
6

Efficient Using Modular Multiplicative Inverse:

As P is prime, we can use Modular Multiplicative Inverse. Using dynamic programming, we can calculate a pre-product array under modulo P such that the value at index i contains the product in the range [0, i]. Similarly, we can calculate the pre-inverse product under modulo P. Now each query can be answered in O(1). 

The inverse product array contains the inverse product in the range [0, i] at index i. So, for the query [L, R], the answer will be Product[R]*InverseProduct[L-1]

Note: We can not calculate the answer as Product[R]/Product[L-1] because the product is calculated under modulo P. If we do not calculate the product under modulo P there is always a possibility of overflow.  

Implementation:

C++




// Product in range Queries in O(1)
#include <bits/stdc++.h>
using namespace std;
#define MAX 100
 
int pre_product[MAX];
int inverse_product[MAX];
 
// Returns modulo inverse of a
// with respect to m using
// extended Euclid Algorithm
// Assumption: a and m are
// coprimes, i.e., gcd(a, m) = 1
int modInverse(int a, int m)
{
    int m0 = m, t, q;
    int x0 = 0, x1 = 1;
 
    if (m == 1)
        return 0;
 
    while (a > 1)
    {
 
        // q is quotient
        q = a / m;
 
        t = m;
 
        // m is remainder now,
        // process same as
        // Euclid's algo
        m = a % m, a = t;
 
        t = x0;
 
        x0 = x1 - q * x0;
 
        x1 = t;
    }
 
    // Make x1 positive
    if (x1 < 0)
        x1 += m0;
 
    return x1;
}
 
// calculating pre_product
// array
void calculate_Pre_Product(int A[],
                           int N, int P)
{
    pre_product[0] = A[0];
 
    for (int i = 1; i < N; i++)
    {
        pre_product[i] = pre_product[i - 1] *
                                        A[i];
        pre_product[i] = pre_product[i] % P;
    }
}
 
// Calculating inverse_product
// array.
void calculate_inverse_product(int A[],
                               int N, int P)
{
    inverse_product[0] = modInverse(pre_product[0], P);
 
    for (int i = 1; i < N; i++)
        inverse_product[i] = modInverse(pre_product[i], P);
}
 
// Function to calculate
// Product in the given range.
int calculateProduct(int A[], int L,
                     int R, int P)
{
    // As our array is 0 based as
    // and L and R are given as 1
    // based index.
    L = L - 1;
    R = R - 1;
    int ans;
 
    if (L == 0)
        ans = pre_product[R];
    else
        ans = pre_product[R] *
              inverse_product[L - 1];
 
    return ans;
}
 
// Driver Code
int main()
{
    // Array
    int A[] = { 1, 2, 3, 4, 5, 6 };
 
    int N = sizeof(A) / sizeof(A[0]);
 
    // Prime P
    int P = 113;
 
    // Calculating PreProduct
    // and InverseProduct
    calculate_Pre_Product(A, N, P);
    calculate_inverse_product(A, N, P);
 
    // Range [L, R] in 1 base index
    int L = 2, R = 5;
    cout << calculateProduct(A, L, R, P)
         << endl;
 
    L = 1, R = 3;
    cout << calculateProduct(A, L, R, P)
         << endl;
    return 0;
}


Java




// Java program to find Product
// in range Queries in O(1)
class GFG
{
 
static int MAX = 100;
int pre_product[] = new int[MAX];
int inverse_product[] = new int[MAX];
 
// Returns modulo inverse of a
// with respect to m using extended
// Euclid Algorithm Assumption: a
// and m are coprimes,
// i.e., gcd(a, m) = 1
int modInverse(int a, int m)
{
    int m0 = m, t, q;
    int x0 = 0, x1 = 1;
 
    if (m == 1)
        return 0;
 
    while (a > 1)
    {
 
        // q is quotient
        q = a / m;
 
        t = m;
 
        // m is remainder now,
        // process same as
        // Euclid's algo
        m = a % m;
        a = t;
 
        t = x0;
 
        x0 = x1 - q * x0;
 
        x1 = t;
    }
 
    // Make x1 positive
    if (x1 < 0)
        x1 += m0;
 
    return x1;
}
 
// calculating pre_product array
void calculate_Pre_Product(int A[],
                           int N, int P)
{
    pre_product[0] = A[0];
 
    for (int i = 1; i < N; i++)
    {
        pre_product[i] = pre_product[i - 1] *
                                        A[i];
        pre_product[i] = pre_product[i] % P;
    }
}
 
// Calculating inverse_product array.
void calculate_inverse_product(int A[],
                               int N, int P)
{
    inverse_product[0] = modInverse(pre_product[0],
                                                P);
 
    for (int i = 1; i < N; i++)
        inverse_product[i] = modInverse(pre_product[i],
                                                     P);
}
 
// Function to calculate Product
// in the given range.
int calculateProduct(int A[], int L,
                     int R, int P)
{
    // As our array is 0 based as and
    // L and R are given as 1 based index.
    L = L - 1;
    R = R - 1;
    int ans;
 
    if (L == 0)
        ans = pre_product[R];
    else
        ans = pre_product[R] *
              inverse_product[L - 1];
 
    return ans;
}
 
// Driver code
public static void main(String[] s)
{
    GFG d = new GFG();
     
    // Array
    int A[] = { 1, 2, 3, 4, 5, 6 };
     
    // Prime P
    int P = 113;
 
    // Calculating PreProduct and
    // InverseProduct
    d.calculate_Pre_Product(A, A.length, P);
    d.calculate_inverse_product(A, A.length,
                                         P);
 
    // Range [L, R] in 1 base index
    int L = 2, R = 5;
    System.out.println(d.calculateProduct(A, L,
                                          R, P));
    L = 1;
    R = 3;
    System.out.println(d.calculateProduct(A, L,
                                          R, P));
         
}
}
 
// This code is contributed by Prerna Saini


Python3




# Python3 implementation of the
# above approach
 
# Returns modulo inverse of a with
# respect to m using extended Euclid
# Algorithm. Assumption: a and m are
# coprimes, i.e., gcd(a, m) = 1
def modInverse(a, m):
 
    m0, x0, x1 = m, 0, 1
 
    if m == 1:
        return 0
 
    while a > 1:
 
        # q is quotient
        q = a // m
        t = m
 
        # m is remainder now, process
        # same as Euclid's algo
        m, a = a % m, t
        t = x0
        x0 = x1 - q * x0
        x1 = t
 
    # Make x1 positive
    if x1 < 0:
        x1 += m0
 
    return x1
 
# calculating pre_product array
def calculate_Pre_Product(A, N, P):
 
    pre_product[0] = A[0]
 
    for i in range(1, N):
     
        pre_product[i] = pre_product[i - 1] * A[i]
        pre_product[i] = pre_product[i] % P
 
# Calculating inverse_product
# array.
def calculate_inverse_product(A, N, P):
 
    inverse_product[0] = modInverse(pre_product[0], P)
 
    for i in range(1, N):
        inverse_product[i] = modInverse(pre_product[i], P)
 
# Function to calculate
# Product in the given range.
def calculateProduct(A, L, R, P):
 
    # As our array is 0 based as
    # and L and R are given as 1
    # based index.
    L = L - 1
    R = R - 1
    ans = 0
 
    if L == 0:
        ans = pre_product[R]
    else:
        ans = pre_product[R] * inverse_product[L - 1]
 
    return ans
 
# Driver Code
if __name__ == "__main__":
 
    # Array
    A = [1, 2, 3, 4, 5, 6]
    N = len(A)
 
    # Prime P
    P = 113
    MAX = 100
     
    pre_product = [None] * (MAX)
    inverse_product = [None] * (MAX)
 
    # Calculating PreProduct
    # and InverseProduct
    calculate_Pre_Product(A, N, P)
    calculate_inverse_product(A, N, P)
 
    # Range [L, R] in 1 base index
    L, R = 2, 5
    print(calculateProduct(A, L, R, P))
 
    L, R = 1, 3
    print(calculateProduct(A, L, R, P))
     
# This code is contributed by Rituraj Jain


C#




// C# program to find Product
// in range Queries in O(1)
using System;
 
class GFG
{
 
    static int MAX = 100;
    int []pre_product = new int[MAX];
    int []inverse_product = new int[MAX];
     
    // Returns modulo inverse of
    // a with respect to m using
    // extended Euclid Algorithm
    // Assumption: a and m are
    // coprimes, i.e., gcd(a, m) = 1
    int modInverse(int a, int m)
    {
        int m0 = m, t, q;
        int x0 = 0, x1 = 1;
     
        if (m == 1)
            return 0;
     
        while (a > 1)
        {
     
            // q is quotient
            q = a / m;
            t = m;
     
            // m is remainder now, process
            // same as Euclid's algo
            m = a % m;
            a = t;
            t = x0;
            x0 = x1 - q * x0;
            x1 = t;
        }
     
        // Make x1 positive
        if (x1 < 0)
            x1 += m0;
     
        return x1;
    }
     
    // calculating pre_product array
    void calculate_Pre_Product(int []A,
                               int N,
                               int P)
    {
        pre_product[0] = A[0];
     
        for (int i = 1; i < N; i++)
        {
            pre_product[i] =
                pre_product[i - 1] *
                               A[i];
                                 
            pre_product[i] =
                pre_product[i] % P;
        }
    }
     
    // Calculating inverse_product
    // array.
    void calculate_inverse_product(int []A,
                                   int N,
                                   int P)
    {
        inverse_product[0] =
                modInverse(pre_product[0], P);
     
        for (int i = 1; i < N; i++)
            inverse_product[i] =
                modInverse(pre_product[i], P);
    }
     
    // Function to calculate Product
    // in the given range.
    int calculateProduct(int []A, int L,
                         int R, int P)
    {
         
        // As our array is 0 based as
        // and L and R are given as 1
        // based index.
        L = L - 1;
        R = R - 1;
        int ans;
     
        if (L == 0)
            ans = pre_product[R];
        else
            ans = pre_product[R] *
                  inverse_product[L - 1];
     
        return ans;
    }
     
    // Driver code
    public static void Main()
    {
        GFG d = new GFG();
         
        // Array
        int []A = { 1, 2, 3, 4, 5, 6 };
         
        // Prime P
        int P = 113;
     
        // Calculating PreProduct and
        // InverseProduct
        d.calculate_Pre_Product(A,
                        A.Length, P);
                         
        d.calculate_inverse_product(A,
                        A.Length, P);
     
        // Range [L, R] in 1 base index
        int L = 2, R = 5;
        Console.WriteLine(
            d.calculateProduct(A, L, R, P));
             
        L = 1;
        R = 3;
        Console.WriteLine(
            d.calculateProduct(A, L, R, P));
    }
}
 
// This code is contributed by vt_m.


Javascript




<script>
    // Javascript program to find Product
    // in range Queries in O(1)
     
    let MAX = 100;
    let pre_product = new Array(MAX);
    let inverse_product = new Array(MAX);
      
    // Returns modulo inverse of
    // a with respect to m using
    // extended Euclid Algorithm
    // Assumption: a and m are
    // coprimes, i.e., gcd(a, m) = 1
    function modInverse(a, m)
    {
        let m0 = m, t, q;
        let x0 = 0, x1 = 1;
      
        if (m == 1)
            return 0;
      
        while (a > 1)
        {
      
            // q is quotient
            q = parseInt(a / m, 10);
            t = m;
      
            // m is remainder now, process
            // same as Euclid's algo
            m = a % m;
            a = t;
            t = x0;
            x0 = x1 - q * x0;
            x1 = t;
        }
      
        // Make x1 positive
        if (x1 < 0)
            x1 += m0;
      
        return x1;
    }
      
    // calculating pre_product array
    function calculate_Pre_Product(A, N, P)
    {
        pre_product[0] = A[0];
      
        for (let i = 1; i < N; i++)
        {
            pre_product[i] =
                pre_product[i - 1] *
                               A[i];
                                  
            pre_product[i] =
                pre_product[i] % P;
        }
    }
      
    // Calculating inverse_product
    // array.
    function calculate_inverse_product(A, N, P)
    {
        inverse_product[0] =
                modInverse(pre_product[0], P);
      
        for (let i = 1; i < N; i++)
            inverse_product[i] =
                modInverse(pre_product[i], P);
    }
      
    // Function to calculate Product
    // in the given range.
    function calculateProduct(A, L, R, P)
    {
          
        // As our array is 0 based as
        // and L and R are given as 1
        // based index.
        L = L - 1;
        R = R - 1;
        let ans;
      
        if (L == 0)
            ans = pre_product[R];
        else
            ans = pre_product[R] *
                  inverse_product[L - 1];
      
        return ans;
    }
          
    // Array
    let A = [ 1, 2, 3, 4, 5, 6 ];
 
    // Prime P
    let P = 113;
 
    // Calculating PreProduct and
    // InverseProduct
    calculate_Pre_Product(A, A.length, P);
 
    calculate_inverse_product(A, A.length, P);
 
    // Range [L, R] in 1 base index
    let L = 2, R = 5;
    document.write(calculateProduct(A, L, R, P) + "</br>");
 
    L = 1;
    R = 3;
    document.write(calculateProduct(A, L, R, P));
       
</script>


Output

7
6

METHOD 3:Using functools 

APPROACH:

This approach uses the reduce() function from the functools module to calculate the product of the range in the array . The input parameters are arr for the input array, L and R for the range, and P for the modulo. The output is the product of the range modulo P, which equals 120 in this case.

ALGORITHM:

  1.  Initialize a variable res to 1.
  2. Iterate over the elements in the range [L-1, R] of the array arr.
  3. For each element in the range, multiply it with res.
  4.  Return res.

Python3




from functools import reduce
 
def product_range(arr, L, R):
    res = reduce(lambda x, y: x*y, arr[L-1:R])
    return res
     
arr = [1, 2, 3, 4, 5, 6]
L, R, P = 2, 5, 229
res = product_range(arr, L, R)
print(f"Input: A[] = {arr}, L = {L}, R = {R}, P = {P}")
print(f"Output: {res % P}")


Output

Input: A[] = [1, 2, 3, 4, 5, 6], L = 2, R = 5, P = 229
Output: 120

The time complexity of the product_range() function in the above code is O(R-L+1)
The space complexity is O(1) 



Last Updated : 24 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads