Open In App

C++ Program for Products of ranges in an array

Last Updated : 20 Jan, 2022
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).  

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;
}


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.  

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;
}


Output :  

7
6

Please refer complete article on Products of ranges in an array for more details!
 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads