![]() |
VOOZH | about |
Mo’s Algorithm can be explained using the range sum query problem, where an array and several queries are given. Each query contains a range [L,R][L, R][L,R], and we need to calculate the sum of elements within that range.
Example:
Input: arr[] = {1, 1, 2, 1, 3, 4, 5, 2, 8}, Query = [0, 4], [1, 3], [2, 4]
Output: Sum of arr[] elements in range [0, 4] is 8
Sum of arr[] elements in range [1, 3] is 4
Sum of arr[] elements in range [2, 4] is 6
Explanation:
Query [0, 4] - 1 + 1 + 2 + 1 + 3 = 8
Query [1, 3] - 1 + 2 + 1 = 4
Query [2, 4] - 2 + 1 + 3 = 6
Table of Content
For each query [L,R][L, R][L,R], traverse the array from index L to R and compute the sum of elements in that range. Repeat this process for every query.
Sum of [0, 4] is 8 Sum of [1, 3] is 4 Sum of [2, 4] is 6
The idea of MO's algorithm is to pre-process all queries so that result of one query can be used in next query. Below are steps.
Steps of MO’s Algorithm
Sum of [1, 3] is 4 Sum of [0, 4] is 8 Sum of [2, 4] is 6
Note: The results may not appear in the same order as the input queries because the queries are sorted. This can be handled by storing original indices.
Why It Works Efficiently
Because queries are sorted in blocks:
Time Complexity
Space Complexity
Important Observations:
Note: A simple and more Efficient solution to solve this problem is to compute prefix sum for all elements from 0 to n-1. Let the prefix sum be stored in an array preSum[] (The value of preSum[i] stores sum of arr[0..i]). Once we have built preSum[], we can traverse through all queries one by one. For every query [L, R], we return value of preSum[R] - preSum[L]. Here processing every query takes O(1) time.