Skip to content
This repository has been archived by the owner on Jan 13, 2022. It is now read-only.

Mo's Algorithm.cpp #487

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions C++ & C/Mo's Algorithm
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Mo's Algorithm implementation in C++
// Author: Omkar Acharekar
// 28 - 10 - 2021


//The idea is to answer the queries in a special order based on the indices.
//We will first answer all queries which have the left index in block 0, then answer all queries which have left index in block 1 and so on.
//And also we will have to answer the queries of a block is a special order, namely sorted by the right index of the queries.


// Implementation

In Mo's algorithm we use two functions for adding an index and for removing an index from the range which we are currently maintaining.



void remove(idx); // TODO: remove value at idx from data structure
void add(idx); // TODO: add value at idx from data structure
int get_answer(); // TODO: extract the current answer of the data structure

int block_size;

struct Query {
int l, r, idx;
bool operator<(Query other) const
{
return make_pair(l / block_size, r) <
make_pair(other.l / block_size, other.r);
}
};

vector<int> mo_s_algorithm(vector<Query> queries) {
vector<int> answers(queries.size());
sort(queries.begin(), queries.end());

// TODO: initialize data structure

int cur_l = 0;
int cur_r = -1;
// invariant: data structure will always reflect the range [cur_l, cur_r]
for (Query q : queries) {
while (cur_l > q.l) {
cur_l--;
add(cur_l);
}
while (cur_r < q.r) {
cur_r++;
add(cur_r);
}
while (cur_l < q.l) {
remove(cur_l);
cur_l++;
}
while (cur_r > q.r) {
remove(cur_r);
cur_r--;
}
answers[q.idx] = get_answer();
}
return answers;
}