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

• Difficulty Level : Hard
• Last Updated : 22 Feb, 2022

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, arr, arr)
Second Query -> arr[] = { 1, 2, 3, 4 }
Third Query -> arr[] = { 1, 2, 3, 4, 6 }
Fourth Query -> sum(arr, arr, arr)

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;``        ``int` `x = i, v = i;` `        ``// 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

 ``

Output:

```10
13```

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

My Personal Notes arrow_drop_up