diff --git a/algorithms/structure/sqrt_decomposition.cpp b/algorithms/structure/sqrt_decomposition.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..92e58ceca10bcb2017bd080e41838172fe4eb399
--- /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];
+  }
+}