C# Coding Test Course, Finding the Product of a Range

Problem Description

There is a given integer array nums and a query array queries. Each query consists of two integers (l, r), requesting the value of nums[l] * nums[l + 1] * ... * nums[r]. The size of the nums array can be up to 10^5, and the length of queries can be up to 10^4. Since the result of the multiplication can be very large, the output must be the remainder when divided by 10^9 + 7.

Input Format

The first line contains the size of the array n and the number of queries q. The second line contains an array nums of n integers, followed by q lines where each line contains the query values l and r.

Output Format

Output the results of the calculations for each query, one result per line.

Example

Input
5 3
2 3 4 5 6
0 2
1 3
2 4
Output
24
60
120

Solution Explanation

To solve this problem, we need a method to quickly compute the product over a range. Simply iterating through the range for each query to calculate the product would lead to a time complexity of O(q * n), which could result in up to 10^9 operations in the worst case. This is impractical, so we use a Prefix Product strategy to reduce time complexity.

Prefix Product Method

First, we store the cumulative product of the elements in the nums array to quickly calculate the results of the queries.

C#
int mod = 1000000007;
int[] prefixProduct = new int[n + 1];
prefixProduct[0] = 1;

for (int i = 1; i <= n; i++) {
    prefixProduct[i] = (int)((1L * prefixProduct[i - 1] * nums[i - 1]) % mod);
}

Here, prefixProduct[i] stores the value of nums[0] * nums[1] * ... * nums[i - 1]. With this structure, we can easily and quickly compute the product over a range.

Calculating the Range Product

Now, for each query (l, r), the range product nums[l] * nums[l + 1] * ... * nums[r] can be calculated as follows:

C#
int result = (int)((1L * prefixProduct[r + 1] * modInverse(prefixProduct[l]) % mod) % mod);

Here, the modInverse function calculates the modular inverse. The inverse can be implemented as follows:

C#
int modInverse(int a) {
    return power(a, mod - 2);
}

int power(int x, int y) {
    int res = 1;
    while (y > 0) {
        if ((y & 1) == 1) {
            res = (int)((1L * res * x) % mod);
        }
        y >>= 1;
        x = (int)((1L * x * x) % mod);
    }
    return res;
}

Final Code

Based on the above explanation, the complete code would look like this:

C#
using System;

class Program {
    static int mod = 1000000007;

    static void Main() {
        string[] firstLine = Console.ReadLine().Split();
        int n = int.Parse(firstLine[0]);
        int q = int.Parse(firstLine[1]);
        int[] nums = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
        int[] prefixProduct = new int[n + 1];
        prefixProduct[0] = 1;

        for (int i = 1; i <= n; i++) {
            prefixProduct[i] = (int)((1L * prefixProduct[i - 1] * nums[i - 1]) % mod);
        }

        for (int i = 0; i < q; i++) {
            string[] query = Console.ReadLine().Split();
            int l = int.Parse(query[0]);
            int r = int.Parse(query[1]);
            int result = (int)((1L * prefixProduct[r + 1] * modInverse(prefixProduct[l]) % mod) % mod);
            Console.WriteLine(result);
        }
    }

    static int modInverse(int a) {
        return power(a, mod - 2);
    }

    static int power(int x, int y) {
        int res = 1;
        while (y > 0) {
            if ((y & 1) == 1) {
                res = (int)((1L * res * x) % mod);
            }
            y >>= 1;
            x = (int)((1L * x * x) % mod);
        }
        return res;
    }
}

Conclusion

In this lecture, we learned how to effectively calculate the product over an array range by using the Prefix Product method and the concept of modular inverses. This method can be applied to handle more complex query processes as well. By utilizing the features of the C# language, efficient code can be written, further enhancing algorithm problem-solving skills.

Additionally, the Prefix Product technique used in this problem can be useful in various forms of query problems, so it is good to try applying it to different problems. Thank you!