From 13bac9590e85c37debbadb852094eff6a9ad59f2 Mon Sep 17 00:00:00 2001 From: Bruno Freitas Tissei <bft15@inf.ufpr.br> Date: Wed, 20 Mar 2019 16:38:07 -0300 Subject: [PATCH] Add sqrt decomposition Signed-off-by: Bruno Freitas Tissei <bft15@inf.ufpr.br> --- algorithms/structure/sqrt_decomposition.cpp | 62 +++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 algorithms/structure/sqrt_decomposition.cpp diff --git a/algorithms/structure/sqrt_decomposition.cpp b/algorithms/structure/sqrt_decomposition.cpp new file mode 100644 index 0000000..92e58ce --- /dev/null +++ b/algorithms/structure/sqrt_decomposition.cpp @@ -0,0 +1,62 @@ +/** + * Sqrt Decomposition + * + * Complexity (time): + * Preprocess -> O(n) + * Query -> O(sqrt(n)) + * Update -> O(1) + * Complexity (space): O(n) + */ + +int v[MAX]; +int block[MAX]; +int block_size; + +/** + * Update v[idx] with val. + * @param idx index of v + * @param val new value of v[idx] + */ +void update(int idx, int val) { + block[idx / block_size] += val - v[idx]; + v[idx] = val; +} + +/** + * Range sum query of v[l..r]. + * @param l,r range + */ +int query(int l, int r) { + int ans = 0; + + // Query sum of elements in case l is inside a block + for (; l < r && ((l % block_size) != 0); ++l) + ans += v[l]; + + // Query sum of each block between l and r + for (; l + block_size <= r; l += block_size) + ans += block[l / block_size]; + + // Query sum of remaining blocks (e.g. r is inside a block) + for (; l <= r; ++l) + ans += v[l]; + + return ans; +} + +/** + * Fills block array with necessary data to perform update and query in + * less than linear time. + * @param n number of elements of v + */ +void preprocess(int n) { + block_size = sqrt(n); + + int idx = -1; + for (int i = 0; i < n; ++i) { + if (i % block_size == 0) + block[++idx] = 0; + + block[idx] += v[i]; + } +} -- GitLab