![]() |
VOOZH | about |
Sparse table concept is used for fast queries on a set of static data (elements do not change). It does preprocessing so that the queries can be answered efficiently.
You are given an integer array arr of length n and an integer q denoting the number of queries. Each query consists of two indices L and R (0 ≤ L ≤ R < n), and asks for the minimum value in the subarray arr[L…R].
Example:
Input: arr[] = [ 7, 2, 3, 0, 5, 10, 3, 12, 18 ]
queries[][] = [ [0, 4], [4, 7], [7, 8] ]
Output: 0 3 12
Explanation: For query 1, the subarray spanning indices 0 through 4 contains the values 7, 2, 3, and 0, and the minimum among them is 0. Similarly, the minimum value in range [4, 7] and [7, 8] are 3 and 12 respectively.
Approach:
The idea is to precompute the minimum values for all subarrays whose lengths are powers of two and store them in a table so that any range-minimum query can be answered in constant time. We build a 2D array
lookupwherelookup[i][j]holds the minimum of the subarray starting atiwith length2^j (j varies from to Log n where n is the length of the input array). For example lookup[0][3] contains minimum of range [0, 7] (starting with 0 and of size 23)How to fill this lookup or sparse table?
The idea is simple, fill in a bottom-up manner using previously computed values. We compute ranges with current power of 2 using values of lower power of two. Each entry for length2^jis derived by combining two overlapping subarrays of length2^(j–1)that were computed in the previous step. For example, to find a minimum of range [0, 7] (Range size is a power of 3), we can use the minimum of following two.
a) Minimum of range [0, 3] (Range size is a power of 2)
b) Minimum of range [4, 7] (Range size is a power of 2)
Based on above example, below is formula,// Minimum of single element subarrays is same // as the only element. lookup[i][0] = arr[i] // If lookup[0][2] <= lookup[4][2], // then lookup[0][3] = lookup[0][2] If lookup[i][j-1] <= lookup[i+2j-1][j-1] lookup[i][j] = lookup[i][j-1] // If lookup[0][2] > lookup[4][2], // then lookup[0][3] = lookup[4][2] Else lookup[i][j] = lookup[i+2j-1][j-1]
Follow the below given steps:
lookup[i][0] = arr[i] for every 0 ≤ i < n.j from 1 up to ⌊log₂n⌋, and for each i from 0 to n – 2^j:lookup[i][j] as the minimum of the two halves:i of length 2^(j–1) (lookup[i][j–1])i + 2^(j–1) of length 2^(j–1) (lookup[i + 2^(j–1)][j–1])[L, R]:k = ⌊log₂(R – L + 1)⌋.[L, R] is min(lookup[L][k], lookup[R – 2^k + 1][k]).How do we handle individual queries?
- Find highest power of 2 that is smaller than or equal to count of elements in given range [L, R]. we get
j = floor(log2(R - L + 1))For [2, 10], j = 3- Compute minimum of last 2^j elements with first 2^j elements in range. For [2, 10], we compare lookup[0][3] (minimum from 0 to 7) and lookup[3][3] (minimum from 3 to 10) and return the minimum of two values.
0 3 12
Time Complexity: O(n * log n), sparse table method supports query operation in O(1) time with O(n Log n) preprocessing time.
Auxiliary Space: O(n * log n)
You are given an integer array arr of length n and an integer q denoting the number of queries. Each query consists of two indices L and R (0 ≤ L ≤ R < n), and asks for the greatest common divisor in the subarray arr[L…R].
Example:
Input: arr[] = [2, 3, 5, 4, 6, 8]
queries[][] = [ [0, 2], [3, 5], [2, 3] ]
Output: 1 2 1
Explanation: For query 1, gcd of elements 2, 3, and 5 is 1 (as all three are primes).
For query 2, gcd of elements 4, 6, and 8 is 2.
For query 3, gcd of elements 5 and 4 is 1 (as 4 and 5 are co-primes).
Approach:
The idea is to exploit the associativity and idempotence of GCD to answer any range‐GCD query in constant time after preprocessing. Since
GCD(a, b, c) = GCD(GCD(a, b), c) = GCD(a, GCD(b, c))
and taking GCD of an overlapping element more than once does not change the result (e.g. GCD(a, b, c) = GCD(GCD(a, b), GCD(b, c))), we can build a sparse table over powers of two just like in the range‐minimum query. Any query range [L, R] can then be covered by two overlapping power‐of‐two intervals whose GCDs we combine to get the answer.
How to handle individual queries?
- Find highest power of 2 that is smaller than or equal to count of elements in given range [L, R]. we get
j = floor(log2(R - L + 1))For [2, 10], j = 3- Compute GCD of last 2^j elements with first 2^j elements in range. For [2, 10], we compute GCD of lookup[0][3] (GCD of 0 to 7) and GCD of lookup[3][3] (GCD of 3 to 10).
Follow the below given steps:
Below is given the implementation:
1 2 1
Time Complexity: O(n * log n)
Auxiliary Space: O(n * log n)