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:

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:

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
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> peformQueries(vector<int>& A,
                          vector<vector<int> >& 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 occured before it
            int id = x + sum(x, idx);
  
            // Making the effect to that
            // value to 0 by subtracting
            // same vaule 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<vector<int> > B = {
        { 4, 2, 4 },
        { 3, 3, 0 },
        { 1, 6, 0 },
        { 4, 3, 5 },
    };
  
    // Get the answer array
    vector<int> ans = peformQueries(A, B);
  
    // printing the answer
    for (int i : ans)
        cout << i << "\n";
  
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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<Integer> peformQueries(Vector<Integer> 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<Integer> 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 occured before it
                int id = x + sum(x, idx);
  
                // Making the effect to that
                // value to 0 by subtracting
                // same vaule 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<Integer> A = new Vector<Integer>(Arrays.asList(a));
  
        // Queries
        int[][] B = { { 4, 2, 4 }, { 3, 3, 0 }, { 1, 6, 0 }, { 4, 3, 5 } };
  
        // Get the answer array
        Vector<Integer> ans = peformQueries(A, B);
  
        // printing the answer
        for (int i : ans)
            System.out.println(i);
    }
}
  
// This code is contributed by
// sanjeev2552
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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 occured before it
            id = x + summation(x, idx)
  
            # Making the effect to that
            # value to 0 by subtracting
            # same vaule 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
chevron_right

Output:
10
13

Time Complexity: O(Q * logN + NlogN)





Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : sanjeev2552

Article Tags :