Monday, October 6, 2025
HomeData Modelling & AIWorking and need of Mo’s Algorithm

Working and need of Mo’s Algorithm

Mo’s Algorithm is a generic algorithm. It can be used in many problems that require processing range queries in a static array, i.e., the array values do not change between the queries. In each query, for a given range [a, b] the idea is to calculate the value based on the array elements between positions of a and b. Since the array is static, the queries can be processed in any order, and Mo’s Algorithm processes the queries in a special order which guarantees that the algorithm works efficiently.

It maintains an active range of the array, and the result of a query concerning the active range is known at each moment. The algorithm processes the queries one by one, and always moves the endpoints of the active range by inserting and removing elements.

Time Complexity: O(N√N*f(N)), where the array has N elements and there are N queries and each insertion and removal of an element takes O(f(N)) time.

The trick in Mo’s algorithm is the order in which the queries are processed:

  • The array is divided into blocks of k = O(√N) elements, and a query [a1, b1] is processed before a query [a2, b2] if either [a1/k] < [a2/k] or [a1/k] = [a2/k] and b1 < b2 is true.
  • Thus, all queries whose left endpoints are in a certain block are processed one after another sorted according to their right endpoints.
  • Using this order, the algorithm only performs O(N√N) operations, because of the left endpoint moves O(N) times O(√N) steps, and the right endpoint moves O(√N) times O(N) steps.
  • Thus, both endpoints move a total of O(N√N) steps during the algorithm.

Example: Consider a problem where there are given a set of queries, each of them corresponding to a range in an array, and the task is to calculate for each query the number of distinct elements in the range. In Mo’s algorithm, the queries are always sorted in the same way, but it depends on the problem of how the answer to the query is maintained. 

  • In this problem, the idea is to maintain an array count[] where count[x] indicates the number of times an element x occurs in the active range.
  • When moving from one query to another query, the active range changes.  For example, if the current range is {4, 2, 5, 4, 2, 4, 3, 3, 4} and the next range is {4, 2, 5, 4, 2, 4, 3, 3, 4}. (ranges are marked as bold)
  • There will be three steps: the left endpoint moves one step to the right, and the right endpoint moves two steps to the right.
  • After each step, the array count[] needs to be updated.
  • After adding an element x, increase the value of count[x] by 1, and if the count[x] = 1 after this also increase the answer to the query by 1.
  • Similarly, after removing an element x, decrease the value of count[x] by 1, and if the count[x] = 0 after this, also decrease the answer to the query by 1.
  • In this problem, the time needed to perform each step is O(1), so the total time complexity of the algorithm is O(N√N).
Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Dominic
32338 POSTS0 COMMENTS
Milvus
86 POSTS0 COMMENTS
Nango Kala
6707 POSTS0 COMMENTS
Nicole Veronica
11871 POSTS0 COMMENTS
Nokonwaba Nkukhwana
11936 POSTS0 COMMENTS
Shaida Kate Naidoo
6825 POSTS0 COMMENTS
Ted Musemwa
7089 POSTS0 COMMENTS
Thapelo Manthata
6779 POSTS0 COMMENTS
Umr Jansen
6781 POSTS0 COMMENTS