Products of ranges in an array

Given an array A[] of size N. Solve Q queries. Find the product in 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

Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Brute Force

For each of the query, 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 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



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 value at index i contains the product in the range [0, i]. Similarly we can calculate the pre-inverse product under modulo P. Now the each query can be answered in O(1).
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 cannot 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 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 = A;        for (int i = 1; i < N; i++)      {         pre_product[i] = pre_product[i - 1] *                                          A[i];         pre_product[i] = pre_product[i] % P;     } }    // Cacluating inverse_product  // array. void calculate_inverse_product(int A[],                                 int N, int P) {     inverse_product = modInverse(pre_product, 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);        // 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 = A;        for (int i = 1; i < N; i++)      {         pre_product[i] = pre_product[i - 1] *                                         A[i];         pre_product[i] = pre_product[i] % P;     } }    // Cacluating inverse_product array. void calculate_inverse_product(int A[],                                 int N, int P) {     inverse_product = modInverse(pre_product,                                                 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 = A         for i in range(1, N):                 pre_product[i] = pre_product[i - 1] * A[i]          pre_product[i] = pre_product[i] % P     # Cacluating inverse_product  # array.  def calculate_inverse_product(A, N, P):         inverse_product = modInverse(pre_product, 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 = A;                for (int i = 1; i < N; i++)         {             pre_product[i] =                  pre_product[i - 1] *                                 A[i];                                                pre_product[i] =                 pre_product[i] % P;         }     }            // Cacluating inverse_product     // array.     void calculate_inverse_product(int []A,                                     int N,                                     int P)     {         inverse_product =                  modInverse(pre_product, 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.

Output :

7
6

My Personal Notes arrow_drop_up Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.

Improved By : vt_m, jit_t, rituraj_jain

Article Tags :
Practice Tags :

1

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.