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
Table of Content
[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.
#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;
}
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