From 5e35ab77fc4b14e3d8a5284da66ff2c6240d4281 Mon Sep 17 00:00:00 2001 From: Om <78009952+OmkarAcharekar@users.noreply.github.com> Date: Fri, 29 Oct 2021 15:50:11 +0530 Subject: [PATCH] Mo's Algorithm.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Algorithm , based on sqrt decomposition, can be used to answer range queries (Q) offline in O((N+Q)√N --- C++ & C/Mo's Algorithm | 61 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 C++ & C/Mo's Algorithm diff --git a/C++ & C/Mo's Algorithm b/C++ & C/Mo's Algorithm new file mode 100644 index 00000000..b9183b36 --- /dev/null +++ b/C++ & C/Mo's Algorithm @@ -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 mo_s_algorithm(vector queries) { + vector 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; +}