# Perform append, update, delete and range sum queries on the given array

Given an array arr[] of size N and the task is to answer Q queries of the following types:

• 1 X 0: Append X at the back of the array.
• 2 X Y: Set arr[X] = Y.
• 3 X 0: Delete arr[X].
• 4 X Y: Find the sum in the range [X, Y].

Note that after deleting arr[X] in query type 3, all the elements after index X will be shifted left by one position.

Examples:

Input: arr[] = {1, 2, 5, 3, 4}, Q[][] = {
{4, 2, 4},
{3, 3, 0},
{1, 6, 0},
{4, 3, 5}}
Output:
10
13
First Query -> sum(arr[1], arr[2], arr[3])
Second Query -> arr[] = { 1, 2, 3, 4 }
Third Query -> arr[] = { 1, 2, 3, 4, 6 }
Fourth Query -> sum(arr[2], arr[3], arr[4])

Input: arr[] = {1, 2, 3, 4, 5}, Q[][] = {
{4, 1, 5},
{3, 3, 0},
{1, 6, 0},
{4, 3, 5},
{2, 4, 10}.
{4, 1, 5}}
Output:
15
15
23

Naive approach: The naive way to solve this problem is to execute the queries directly on the given array which will have a time complexity of O(Q * N).

Efficient approach:

• As there are some data structures like Segment tree or BIT(Fenwick Tree) that provide the point update and range sum in O(logN) per query.
• The post uses a Fenwick Tree to do the same, so it is highly recommended to go through point update in Fenwick Tree.
• But the main problem is performing the delete operation ( type-3 queries ). After performing, there is a need for shifting, which will again lead to O(Q * N) in the worst case.
• A trick can be used that, after deleting an element, just update the value at A[X] = 0 and map the index after X to X + number of elements deleted before X.
• To find the number of elements deleted before X, there will be another Fenwick tree ( as idx in the implementation ) used and keep adding 1 at that index where the delete operation is being performed.
• This means at the time of fetching or getting a particular index, a query can be made to the idx tree and update the index X to X + sum(X, idx).

Below is the implementation of the above approach:

## C++

 `// C++ implementation of the approach` `#include ` `using` `namespace` `std;`   `// Size of the array (MAX)` `const` `int` `N = 2e5 + 10;`   `// To store the sum of` `// the array elements` `vector<``int``> bit(N, 0);`   `// To keep track of how many type 3` `// queries have been performed before` `// a particular index` `vector<``int``> idx(N, 0);`   `// Function to perform the point` `// update in Fenwick tree` `void` `update(``int` `idx, ``int` `val,` `            ``vector<``int``>& bitt)` `{` `    ``while` `(idx < N) {` `        ``bitt[idx] += val;` `        ``idx += idx & (-idx);` `    ``}` `}`   `// Function to return the sum` `// of the elements A[1...idx]` `// from BIT` `int` `sum(``int` `idx,` `        ``vector<``int``>& bitt)` `{`   `    ``int` `res = 0;` `    ``while` `(idx > 0) {` `        ``res += bitt[idx];` `        ``idx -= idx & (-idx);` `    ``}`   `    ``return` `res;` `}`   `// Function to perform the queries and` `// return the answer vector` `vector<``int``> performQueries(vector<``int``>& A,` `                          ``vector >& B)` `{`   `    ``// For 1 bases indexing` `    ``// insert 0 in the vector` `    ``A.insert(A.begin(), 0);`   `    ``// Updated size of the vector` `    ``int` `n = (``int``)A.size();`   `    ``// Updating the bit tree` `    ``for` `(``int` `i = 1; i < n; ++i) {` `        ``update(i, A[i], bit);` `    ``}`   `    ``// Vector to store the answers` `    ``// of range sum` `    ``vector<``int``> ans;`   `    ``// Iterating in the query` `    ``// vector` `    ``for` `(``auto` `i : B) {`   `        ``int` `type = i[0];` `        ``int` `x = i[1], v = i[2];`   `        ``// If the query is of` `        ``// type 1` `        ``if` `(type == 1) {`   `            ``// Updating the tree` `            ``// with x in the last` `            ``update(n, x, bit);`   `            ``// Pushing back the value` `            ``// in the original vector` `            ``A.push_back(x);`   `            ``// Incrementing the size` `            ``// of the vector by 1` `            ``n++;` `        ``}`   `        ``// If the query is of type 2` `        ``else` `if` `(type == 2) {`   `            ``// Getting the updated index` `            ``// in case of any query of` `            ``// type 3 occurred before it` `            ``int` `id = x + sum(x, idx);`   `            ``// Making the effect to that` `            ``// value to 0 by subtracting` `            ``// same value from the tree` `            ``update(id, -A[id], bit);`   `            ``// Updating the A[id] to v` `            ``A[id] = v;`   `            ``// Now update the` `            ``// bit by v at x` `            ``update(id, v, bit);` `        ``}`   `        ``// If the query is of type 3` `        ``else` `if` `(type == 3) {`   `            ``// Get the current index` `            ``int` `id = x + sum(x, idx);`   `            ``// Remove the effect of that` `            ``// index from the bit tree` `            ``update(id, -A[id], bit);`   `            ``// Update the idx tree` `            ``// because one element has` `            ``// been deleted` `            ``update(x, 1, idx);`   `            ``// Update the idx val to 0` `            ``A[id] = 0;` `        ``}`   `        ``// If the query is of type 4` `        ``else` `{`   `            ``// Get the updated range` `            ``int` `xx = x + sum(x, idx);` `            ``int` `vv = v + sum(v, idx);`   `            ``// Push_back the value` `            ``ans.push_back(sum(vv, bit)` `                          ``- sum(xx - 1, bit));` `        ``}` `    ``}`   `    ``return` `ans;` `}`   `// Driver code` `int` `main()` `{` `    ``vector<``int``> A = { 1, 2, 5, 3, 4 };`   `    ``// Queries` `    ``vector > B = {` `        ``{ 4, 2, 4 },` `        ``{ 3, 3, 0 },` `        ``{ 1, 6, 0 },` `        ``{ 4, 3, 5 },` `    ``};`   `    ``// Get the answer array` `    ``vector<``int``> ans = performQueries(A, B);`   `    ``// printing the answer` `    ``for` `(``int` `i : ans)` `        ``cout << i << ``"\n"``;`   `    ``return` `0;` `}`

## Java

 `// Java implementation of the approach ` `import` `java.util.*;`   `class` `GFG {`   `    ``// Size of the array (MAX)` `    ``static` `int` `N = (``int``) 2e5 + ``10``;`   `    ``// To store the sum of` `    ``// the array elements` `    ``static` `int``[] bit = ``new` `int``[N];`   `    ``// To keep track of how many type 3` `    ``// queries have been performed before` `    ``// a particular index` `    ``static` `int``[] idx = ``new` `int``[N];`   `    ``// Function to perform the point` `    ``// update in Fenwick tree` `    ``static` `void` `update(``int` `idx, ``int` `val, ``int``[] bitt) {` `        ``while` `(idx < N) {` `            ``bitt[idx] += val;` `            ``idx += idx & (-idx);` `        ``}` `    ``}`   `    ``// Function to return the sum` `    ``// of the elements A[1...idx]` `    ``// from BIT` `    ``static` `int` `sum(``int` `idx, ``int``[] bitt) {`   `        ``int` `res = ``0``;` `        ``while` `(idx > ``0``) {` `            ``res += bitt[idx];` `            ``idx -= idx & (-idx);` `        ``}`   `        ``return` `res;` `    ``}`   `    ``// Function to perform the queries and` `    ``// return the answer vector` `    ``static` `Vector performQueries(Vector A, ``int``[][] B) {`   `        ``// For 1 bases indexing` `        ``// insert 0 in the vector` `        ``A.insertElementAt(``0``, ``0``);`   `        ``// Updated size of the vector` `        ``int` `n = (``int``) A.size();`   `        ``// Updating the bit tree` `        ``for` `(``int` `i = ``1``; i < n; ++i) {` `            ``update(i, A.elementAt(i), bit);` `        ``}`   `        ``// Vector to store the answers` `        ``// of range sum` `        ``Vector ans = ``new` `Vector<>();`   `        ``// Iterating in the query` `        ``// vector` `        ``for` `(``int``[] i : B) {`   `            ``int` `type = i[``0``];` `            ``int` `x = i[``1``], v = i[``2``];`   `            ``// If the query is of` `            ``// type 1` `            ``if` `(type == ``1``) {`   `                ``// Updating the tree` `                ``// with x in the last` `                ``update(n, x, bit);`   `                ``// Pushing back the value` `                ``// in the original vector` `                ``A.add(x);`   `                ``// Incrementing the size` `                ``// of the vector by 1` `                ``n++;` `            ``}`   `            ``// If the query is of type 2` `            ``else` `if` `(type == ``2``) {`   `                ``// Getting the updated index` `                ``// in case of any query of` `                ``// type 3 occurred before it` `                ``int` `id = x + sum(x, idx);`   `                ``// Making the effect to that` `                ``// value to 0 by subtracting` `                ``// same value from the tree` `                ``update(id, -A.elementAt(id), bit);`   `                ``// Updating the A[id] to v` `                ``A.set(id, v);`   `                ``// Now update the` `                ``// bit by v at x` `                ``update(id, v, bit);` `            ``}`   `            ``// If the query is of type 3` `            ``else` `if` `(type == ``3``) {`   `                ``// Get the current index` `                ``int` `id = x + sum(x, idx);`   `                ``// Remove the effect of that` `                ``// index from the bit tree` `                ``update(id, -A.elementAt(id), bit);`   `                ``// Update the idx tree` `                ``// because one element has` `                ``// been deleted` `                ``update(x, ``1``, idx);`   `                ``// Update the idx val to 0` `                ``A.set(id, ``0``);` `            ``}`   `            ``// If the query is of type 4` `            ``else` `{`   `                ``// Get the updated range` `                ``int` `xx = x + sum(x, idx);` `                ``int` `vv = v + sum(v, idx);`   `                ``// Push_back the value` `                ``ans.add(sum(vv, bit) - sum(xx - ``1``, bit));` `            ``}` `        ``}`   `        ``return` `ans;` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `main(String[] args) {` `        ``Integer[] a = { ``1``, ``2``, ``5``, ``3``, ``4` `};` `        ``Vector A = ``new` `Vector(Arrays.asList(a));`   `        ``// Queries` `        ``int``[][] B = { { ``4``, ``2``, ``4` `}, { ``3``, ``3``, ``0` `}, { ``1``, ``6``, ``0` `}, { ``4``, ``3``, ``5` `} };`   `        ``// Get the answer array` `        ``Vector ans = peformQueries(A, B);`   `        ``// printing the answer` `        ``for` `(``int` `i : ans)` `            ``System.out.println(i);` `    ``}` `}`   `// This code is contributed by` `// sanjeev2552`

## Python3

 `# Python implementation of the approach`   `# Size of the array (MAX)` `N ``=` `int``(``2e5``) ``+` `10`   `# To store the sum of` `# the array elements` `bit ``=` `[``0``] ``*` `N`   `# To keep track of how many type 3` `# queries have been performed before` `# a particular index` `idx ``=` `[``0``] ``*` `N`   `# Function to perform the point` `# update in Fenwick tree` `def` `update(index: ``int``, val: ``int``, bitt: ``list``):` `    ``while` `index < N:` `        ``bitt[index] ``+``=` `val` `        ``index ``+``=` `index & ``-``index`   `# Function to return the sum` `# of the elements A[1...idx]` `# from BIT` `def` `summation(index: ``int``, bitt: ``list``) ``-``> ``int``:` `    ``res ``=` `0` `    ``while` `index > ``0``:` `        ``res ``+``=` `bitt[index]` `        ``index ``-``=` `index & ``-``index` `    ``return` `res`   `# Function to perform the queries and` `# return the answer vector` `def` `performQueries(A: ``list``, B: ``list``) ``-``> ``list``:` `    ``global` `bit, idx`   `    ``# For 1 bases indexing` `    ``# insert 0 in the vector` `    ``A.insert(``0``, ``0``)`   `    ``# Updated size of the vector` `    ``n ``=` `len``(A)`   `    ``# Updating the bit tree` `    ``for` `i ``in` `range``(``1``, n):` `        ``update(i, A[i], bit)`   `    ``# Vector to store the answers` `    ``# of range sum` `    ``ans ``=` `[]`   `    ``# Iterating in the query` `    ``# vector` `    ``for` `i ``in` `B:` `        ``type` `=` `i[``0``]` `        ``x ``=` `i[``1``]` `        ``v ``=` `i[``2``]`   `        ``# If the query is of` `        ``# type 1` `        ``if` `type` `=``=` `1``:`   `            ``# Updating the tree` `            ``# with x in the last` `            ``update(n, x, bit)`   `            ``# Pushing back the value` `            ``# in the original vector` `            ``A.append(x)`   `            ``# Incrementing the size` `            ``# of the vector by 1` `            ``n ``+``=` `1`   `        ``# If the query is of type 2` `        ``elif` `type` `=``=` `2``:`   `            ``# Getting the updated index` `            ``# in case of any query of` `            ``# type 3 occurred before it` `            ``id` `=` `x ``+` `summation(x, idx)`   `            ``# Making the effect to that` `            ``# value to 0 by subtracting` `            ``# same value from the tree` `            ``update(``id``, ``-``A[``id``], bit)`   `            ``# Updating the A[id] to v` `            ``A[``id``] ``=` `v`   `            ``# Now update the` `            ``# bit by v at x` `            ``update(``id``, v, bit)`   `        ``# If the query is of type 3` `        ``elif` `type` `=``=` `3``:`   `            ``# Get the current index` `            ``id` `=` `x ``+` `summation(x, idx)`   `            ``# Remove the effect of that` `            ``# index from the bit tree` `            ``update(``id``, ``-``A[``id``], bit)`   `            ``# Update the idx tree` `            ``# because one element has` `            ``# been deleted` `            ``update(x, ``1``, idx)`   `            ``# Update the idx val to 0` `            ``A[``id``] ``=` `0`   `        ``# If the query is of type 4` `        ``else``:`   `            ``# Get the updated range` `            ``xx ``=` `x ``+` `summation(x, idx)` `            ``vv ``=` `v ``+` `summation(v, idx)`   `            ``# Push_back the value` `            ``ans.append(summation(vv, bit) ``-` `summation(xx ``-` `1``, bit))` `    ``return` `ans`     `# Driver Code` `if` `__name__ ``=``=` `"__main__"``:` `    ``A ``=` `[``1``, ``2``, ``5``, ``3``, ``4``]`   `    ``# Queries` `    ``B ``=` `[[``4``, ``2``, ``4``], [``3``, ``3``, ``0``], [``1``, ``6``, ``0``], [``4``, ``3``, ``5``]]`   `    ``# Get the answer array` `    ``ans ``=` `performQueries(A, B)`   `    ``# printing the answer` `    ``for` `i ``in` `ans:` `        ``print``(i)`   `# This code is contributed by` `# sanjeev2552`

## Javascript

 ``

## C#

 `// C# implementation of the approach` `using` `System;` `using` `System.Collections.Generic;` `using` `System.Linq;`   `class` `GFG {` `// Size of the array (MAX)` `static` `int` `N = (``int``) 2e5 + 10;` `// To store the sum of` `// the array elements` `static` `int``[] bit = ``new` `int``[N];` `// To keep track of how many type 3` `// queries have been performed before` `// a particular index` `static` `int``[] idx = ``new` `int``[N];` `// Function to perform the point` `// update in Fenwick tree` `static` `void` `update(``int` `idx, ``int` `val, ``int``[] bitt) {` `    ``while` `(idx < N) {` `        ``bitt[idx] += val;` `        ``idx += idx & (-idx);` `    ``}` `}` `// Function to return the sum` `// of the elements A[1...idx]` `// from BIT` `static` `int` `sum(``int` `idx, ``int``[] bitt) {` `    ``int` `res = 0;` `    ``while` `(idx > 0) {` `        ``res += bitt[idx];` `        ``idx -= idx & (-idx);` `    ``}` `    ``return` `res;` `}` `// Function to perform the queries and` `// return the answer vector` `static` `List<``int``> performQueries(List<``int``> A, ``int``[][] B) {`   `// For 1 bases indexing` `    ``// insert 0 in the vector` `    ``A.Insert(0, 0);` `     ``// Updated size of the vector` `    ``int` `n = A.Count();` `   ``// Updating the bit tree` `    ``for` `(``int` `i = 1; i < n; ++i) {` `        ``update(i, A.ElementAt(i), bit);` `    ``}` `    ``// Vector to store the answers` `    ``// of range sum` `    ``List<``int``> ans = ``new` `List<``int``>();` ` ``// Iterating in the query` `    ``// vector` `    ``foreach` `(``int``[] i ``in` `B) {` `        ``int` `type = i[0];` `        ``int` `x = i[1], v = i[2];` `    ``// If the query is of` `        ``// type 1` `        ``if` `(type == 1) {` `            ``// Updating the tree` `            ``// with x in the last` `            ``update(n, x, bit);` `                 ``// Pushing back the value` `            ``// in the original vector` `            ``A.Add(x);` `               ``// Incrementing the size` `            ``// of the vector by 1` `            ``n++;` `        ``}` `              ``// If the query is of type 2` `        ``else` `if` `(type == 2) {` `             ``// Getting the updated index` `            ``// in case of any query of` `            ``// type 3 occurred before it` `            ``int` `id = x + sum(x, idx);` `             ``// Making the effect to that` `            ``// value to 0 by subtracting` `            ``// same value from the tree` `            ``update(id, -A.ElementAt(id), bit);` `                  ``// Updating the A[id] to v` `            ``A[id] = v;` `              ``// Now update the` `            ``// bit by v at x` `            ``update(id, v, bit);` `        ``}` `         ``// If the query is of type 3` `        ``else` `if` `(type == 3) {` `               ``// Get the current index` `            ``int` `id = x + sum(x, idx);` `              ``// Remove the effect of that` `            ``// index from the bit tree` `            ``update(id, -A.ElementAt(id), bit);` `                 ``// Update the idx tree` `            ``// because one element has` `            ``// been deleted` `            ``update(x, 1, idx);` `             ``// Update the idx val to 0` `            ``A[id] = 0;` `        ``}` `           ``// If the query is of type 4` `        ``else` `{` `               ``// Get the updated range` `            ``int` `xx = x + sum(x, idx);` `            ``int` `vv = v + sum(v, idx);` `            `  `            ``// Push_back the value` `            ``ans.Add(sum(vv, bit) - sum(xx - 1, bit));` `        ``}` `    ``}`   `    ``return` `ans;` `}` `// Driver code` `public` `static` `void` `Main(``string``[] args) {` `   ``List<``int``> A = ``new` `List<``int``>(``new` `int``[] { 1, 2, 5, 3, 4 });`   `    ``// Queries` `    ``int``[][] B = ``new` `int``[][] {` `        ``new` `int``[] { 4, 2, 4 },` `        ``new` `int``[] { 3, 3, 0 },` `        ``new` `int``[] { 1, 6, 0 },` `        ``new` `int``[] { 4, 3, 5 }` `    ``};`   ` ``// Get the answer array` `    ``List<``int``> ans = performQueries(A, B);` `   ``// printing the answer` `    ``foreach` `(``int` `i ``in` `ans)` `        ``Console.WriteLine(i);` `}` `}`

Output:

```10
13```

Time Complexity: O(Q * logN + NlogN)
Auxiliary Space: O(N).

Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!

Previous
Next