Products of ranges in an array
Last Updated :
24 Apr, 2023
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>
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>
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:
- Initialize a variable res to 1.
- Iterate over the elements in the range [L-1, R] of the array arr.
- For each element in the range, multiply it with res.
- 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}")
OutputInput: 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)
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem