Products of ranges in an array
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> |
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> |
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:
- 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}" ) |
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)
Please Login to comment...