MO's Algorithm Introduction

Last Updated : 19 Feb, 2026

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

Try It Yourself
redirect icon

[Naive Approach] – Linearly Compute Sum for Every Query – O(n × m) Time and O(1) Space

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.

C++
#include <iostream>
using namespace std;

// Structure to represent a query range
struct Query
{
    int L, R;
};

// Prints sum of all query ranges. m is number of queries
// n is the size of the array.
void printQuerySums(int arr[], int n, Query q[], int m)
{
    for (int i = 0; i < m; i++)
    {
        int L = q[i].L, R = q[i].R;

        int sum = 0;
        for (int j = L; j <= R; j++)
            sum += arr[j];

        cout << "Sum of [" << L << ", " << R << "] is " << sum << endl;
    }
}

int main()
{
    int arr[] = {1, 1, 2, 1, 3, 4, 5, 2, 8};
    int n = sizeof(arr) / sizeof(arr[0]);

    Query q[] = {{0, 4}, {1, 3}, {2, 4}};
    int m = sizeof(q) / sizeof(q[0]);

    printQuerySums(arr, n, q, m);
    return 0;
}
Java
import java.util.*;
 
// Class to represent a query range 
class Query{ 
    int L; 
    int R; 
    Query(int L, int R){
        this.L = L;
        this.R = R;
    }
} 

class GFG
{
    // Prints sum of all query ranges. m is number of queries
    // n is the size of the array.
    static void printQuerySums(int arr[], int n, ArrayList<Query> q, int m)
    {
        // One by one compute sum of all queries
        for (int i=0; i<m; i++)
        {
            // Left and right boundaries of current range