Open In App

Update and Print for all the Query

Last Updated : 03 May, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of length N consisting of a positive integer, the task is to complete the Q queries and print values accordingly which consists of two types of operations:

  • Operation 1: Update all the indices of the array to its digit sum which lies under the range L and R(0 ? L, R ? N-1).
  • Operation 2: Print the value of the array at that index.

Examples:

Input: N = 5, arr[] = {1, 420, 69, 1434, 2023}, Q = 8, queries[][] = [[1, 1, 2], [2, 1], [2, 2], [2, 3], [1, 1, 4], [2, 0], [2, 2], [2, 4]]
Output: [6, 15, 1434, 1, 6, 7]
Explanation:  In the beginning, arr[] = [1, 420, 69, 1434, 2023]

  • 1st query is [1, 1, 2] means operation 1 is used so arr[1] = 4 + 2 + 0 = 6 and arr[2] = 6 + 9 = 15, after updating array arr = [1, 6, 15, 1434, 2023]
  • 2nd query is [2, 1] means operation 2 is used and we need to print arr[1] = 6
  • 3rd query is [2, 2] so, arr[2] = 15
  • 4th query is [2, 3] so, arr[3] = 1434
  • 5th query is [1, 1, 4] so, after updating the array arr = [1, 6, 6, 12, 7]
  • 6th query is [2, 0] so, arr[0] = 1
  • 7th query is [2, 2] so, arr[2] = 6
  • 8th query is [2, 4] so, arr[4] = 7

So in the final, we’ll return [6, 15, 1434, 1, 6, 7]

Approach: The problem can be solved based on the following idea:

We will use Segment Tree to solve this problem:

For input arr = [1, 420, 69, 1434, 2023] (N = 5)
Digitsum of every element till it is greater equal to 10

  • 1 -> [1]
  • 420 -> [420, 6]
  • 69 -> [69, 15, 6]
  • 1434 -> [1434, 12, 3]
  • 2023 -> [2023, 7]

Initially, we will make segment tree for the given array in which the nodes contains value 0.

                (1, 0, 4, 0)
                  /       \
        (2, 0, 2, 0)         (3, 3, 4, 0)
       /       \     /   \
     (4, 0, 1, 0)   (5, 2, 2, 0)  (6, 3, 3, 0) (7, 4, 4, 0)
        /          \
    (8, 0, 0, 0)  (9, 1, 1, 0)
    
Each nodes denotes (node_number, start, end, value), where (start, end) is (0, N-1) at the start

Now, after 1st query that is [1, 1, 2] tree will look like:

          (1, 0, 4, 0)
                  /       \
        (2, 0, 2, 0)         (3, 3, 4, 0)
       /       \     /   \
     (4, 0, 1, 0)   (5, 2, 2, 1)  (6, 3, 3, 0) (7, 4, 4, 0)
        /          \
    (8, 0, 0, 0)  (9, 1, 1, 1)
    
2nd query is [2, 1] so we will traverse the tree from root to the node which has (start, end) equivalent to (1, 1) and calculate the total sum of value. So root to leaf path for (1, 1) from above tree is 1 -> 2 -> 4 -> 9 and sum of its values are: 0 + 0 + 0 + 1 = 1 and for arr[1] = 420, we know digitsum list of 420 that is: [420, 6] so the 1st index value is 6 which we will print.

3rd query is [2, 2] so the path from root to leaf having (start, end) = (2, 2) is: 1 -> 2-> 5 and sum of its values are: 0 + 0 + 1 = 1 and for arr[2] = 69, we know digitsum list of 69 that is: [69, 15, 6] and 1st index of the list is 15 which we will print.

Similarly, for the 4th query which is [2, 3] the root to leaf path will be: 1 -> 3 -> 6 and sum of values are: 0 + 0 + 0 = 0 and for arr[3] = 1434, list of digitsum is:
[1434, 12, 3] in which the 0th index is 1434 which we will print.

For 5th query which is [1, 1, 4] which means we have to increment the values of nodes by 1 which lies under (1, 4) so the tree becomes:

          (1, 0, 4, 0)
                  /       \
        (2, 0, 2, 0)         (3, 3, 4, 1)
       /       \     /   \
     (4, 0, 1, 0)   (5, 2, 2, 2)  (6, 3, 3, 0) (7, 4, 4, 0)
        /          \
    (8, 0, 0, 0)  (9, 1, 1, 2)

Now for the 6th query which is [2, 0] the path will be: 1 -> 2 -> 4 -> 8 and the sum of the values are: 0 + 0 + 0 + 0 = 0, and for arr[0] = 1, the digitsum list is: [1], so for 0th index we will print 1.

For the 7th query which is [2, 2] the path will be: 1 -> 2 -> 5 and the sum of the values are: 0 + 0 + 2 = 2, and for arr[2] = 69, the digitsum list is: [69, 15, 6], so for the 2nd index we will print 6.

For the 8th query which is [2, 4], the path will be: 1 -> 3 -> 4 and the sum of the values are: 0 + 1 + 0 = 1, and for the arr[4] = 2023, the digitsum list id: [2023, 7], so for the 1st index we will print 7.

Steps to solve the problem:

  • Firstly, make a Hash Map that contains the list of the digit sum of each element as the value and as for the key we will store the indices. So for the above test case, Hash Map will contain: [[0 -> [1]], [1 -> [420, 6]], [2 -> [69, 15, 6]], [3 -> [1434, 12, 3]], [4 -> [2023, 7]]].
  • After that, make a segment tree in which initially every node contains the value 0.
  • Now, we will traverse the query list and if we got the first integer as 1 then we will apply 1st operation or if we get the first integer as 2 then we will apply 2nd operation.
  • For the 1st operation, we will update the segment tree and increment the nodes by which (start, end) lies between the range given in the query.
  • For the 2nd operation, we will traverse from the root of the segment tree to the leaf whose (start, end) is equal to the given index in the query, and while traversing we will keep a variable idx updated with the sum of the values of the nodes in the root to leaf path. 
  • After traversing, we will fetch the digit sum list from the Hash Map for that query index and check if idx is less than the size of the list we will print that particular index value otherwise we will print the last value of the list.

Below is the implementation of the above approach:

C++




// C++ Algorithm for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Initializing a global segment tree
int tree[20005];
 
// Initializing a global index variable
int idx;
 
// Function which will return the
// digit sum of an integer n
int getSum(int n)
{
    int sum = 0;
    while (n != 0) {
        sum = sum + n % 10;
        n = n / 10;
    }
    return sum;
}
 
// Function which will build the
// segment tree and initialize every
// node with the value 0
void buildTree(int node, int start, int end)
{
    if (start == end) {
        tree[node] = 0;
        return;
    }
    int mid = (start + end) / 2;
    int left = node * 2;
    int right = (node * 2) + 1;
    buildTree(left, start, mid);
    buildTree(right, mid + 1, end);
    tree[node] = 0;
}
 
// Function which will update the
// segment tree when operation 1 is in
// act and will increment the node value
// by 1 if it lies between the range
// of given query
void updateTree(int node, int start, int end, int l, int r)
{
    if (l > end || start > r)
        return;
    if (l <= start && end <= r) {
        tree[node]++;
        return;
    }
    int mid = (start + end) / 2;
    updateTree(node * 2, start, mid, l, r);
    updateTree(node * 2 + 1, mid + 1, end, l, r);
}
 
// Function which will return the idx
// after adding every nodes values
// which lies in the path from root
// to leaf in the segment tree
void getIndex(int node, int start, int end, int index)
{
    if (index >= start && index <= end) {
        if (start == end) {
            idx += tree[node];
            return;
        }
        idx += tree[node];
        int mid = (start + end) / 2;
        getIndex(node * 2, start, mid, index);
        getIndex(node * 2 + 1, mid + 1, end, index);
    }
    else
        return;
}
 
// Function which will update the
// array and will print the values
// for asked queries
void updateAndPrint(int arr[], int N,
                    vector<vector<int> > queries, int Q)
{
 
    // Map which will be used to
    // store the list of digit sum of
    // the array elements
    map<int, vector<int> > digitSumList;
    for (int i = 0; i < N; i++) {
        vector<int> digitSum;
        int x = arr[i];
 
        // Finding and adding the
        // digit sum while x > 9
        digitSum.push_back(x);
        while (x > 9) {
            x = getSum(x);
            digitSum.push_back(x);
        }
 
        // Adding the list in the
        // Hash Map mapped with the
        // index value
        digitSumList[i] = digitSum;
    }
 
    // Calling the build Function
    // which will construct the segment
    // tree with initial value 0 in
    // the nodes
    buildTree(1, 0, N - 1);
 
    // Traversing the query
    for (int i = 0; i < Q; i++) {
        vector<int> query = queries[i];
 
        // If the first value is 1,
        // which means we have to apply
        // 1st operation
        if (query[0] == 1) {
 
            // Calling the update function
            // of the segment tree
            updateTree(1, 0, N - 1, query[1], query[2]);
        }
 
        // Else 2nd operation
        // comes in act
        else {
 
            // Finding idx value which
            // will be used to fetch the
            // digit sum from the list
            idx = 0;
 
            // Calling getIndex function
            // which will return the value
            // of idx after calculating
            getIndex(1, 0, N - 1, query[1]);
 
            // Fetching the digit sum
            // list from the Hash Map
            vector<int> digitSum = digitSumList[query[1]];
 
            // If idx is greater than
            // digitSum list size means
            // we have to return the
            // last value present in
            // the list
            if (digitSum.size() <= idx)
                cout << digitSum[digitSum.size() - 1]
                     << " ";
 
            // Else we have to return
            // that indexed value from
            // the digitSum list
            else {
                cout << digitSum[idx] << " ";
            }
        }
    }
}
 
// Driver Code
int main()
{
    int N = 5;
    int arr[] = { 1, 420, 69, 1434, 2023 };
    int Q = 8;
    vector<vector<int> > queries;
    vector<int> al;
    al.push_back(1);
    al.push_back(1);
    al.push_back(2);
    queries.push_back(al);
    al.clear();
    al.push_back(2);
    al.push_back(1);
    queries.push_back(al);
    al.clear();
    al.push_back(2);
    al.push_back(2);
    queries.push_back(al);
    al.clear();
    al.push_back(2);
    al.push_back(3);
    queries.push_back(al);
    al.clear();
    al.push_back(1);
    al.push_back(1);
    al.push_back(4);
    queries.push_back(al);
    al.clear();
    al.push_back(2);
    al.push_back(0);
    queries.push_back(al);
    al.clear();
    al.push_back(2);
    al.push_back(2);
    queries.push_back(al);
    al.clear();
    al.push_back(2);
    al.push_back(4);
    queries.push_back(al);
 
    // Function call
    updateAndPrint(arr, N, queries, Q);
    return 0;
}
// This code is contributed by prasad264


Java




// Java Algorithm for the above approach
 
import java.util.*;
 
class GFG {
 
    // Driver Code
    public static void main(String[] args)
    {
        int N = 5;
        int[] arr = { 1, 420, 69, 1434, 2023 };
        int Q = 8;
        List<List<Integer> > queries = new ArrayList<>();
        List<Integer> al = new ArrayList<>();
        al.add(1);
        al.add(1);
        al.add(2);
        queries.add(al);
        al = new ArrayList<>();
        al.add(2);
        al.add(1);
        queries.add(al);
        al = new ArrayList<>();
        al.add(2);
        al.add(2);
        queries.add(al);
        al = new ArrayList<>();
        al.add(2);
        al.add(3);
        queries.add(al);
        al = new ArrayList<>();
        al.add(1);
        al.add(1);
        al.add(4);
        queries.add(al);
        al = new ArrayList<>();
        al.add(2);
        al.add(0);
        queries.add(al);
        al = new ArrayList<>();
        al.add(2);
        al.add(2);
        queries.add(al);
        al = new ArrayList<>();
        al.add(2);
        al.add(4);
        queries.add(al);
 
        // Function call
        updateAndPrint(arr, N, queries, Q);
    }
 
    // Initializing a global segment tree
    static int[] tree;
 
    // Initializing a global index variable
    static int idx;
 
    // Function which will update the
    // array and will print the values
    // for asked queries
    public static void
    updateAndPrint(int[] arr, int N,
                   List<List<Integer> > queries, int Q)
    {
 
        // Hash Map which will be used to
        // store the list of digit sum of
        // the array elements
        Map<Integer, List<Integer> > digitSumList
            = new HashMap<>();
 
        for (int i = 0; i < N; i++) {
            List<Integer> digitSum = new ArrayList<>();
            int x = arr[i];
 
            // Finding and adding the
            // digit sum while x > 9
            digitSum.add(x);
            while (x > 9) {
                x = getSum(x);
                digitSum.add(x);
            }
 
            // Adding the list in the
            // Hash Map mapped with the
            // index value
            digitSumList.put(i, digitSum);
        }
 
        // Initializing the global
        // variable
        tree = new int[N * 4];
        // Calling the build Function
        // which will construct the segment
        // tree with initial value 0 in
        // the nodes
        buildTree(1, 0, N - 1);
 
        // Traversing the query
        for (int i = 0; i < Q; i++) {
 
            List<Integer> query = queries.get(i);
 
            // If the first value is 1,
            // which means we have to apply
            // 1st operation
            if (query.get(0) == 1) {
 
                // Calling the update function
                // of the segment tree
                updateTree(1, 0, N - 1, query.get(1),
                           query.get(2));
            }
 
            // Else 2nd operation
            // comes in act
            else {
 
                // Finding idx value which
                // will be used to fetch the
                // digit sum from the list
                idx = 0;
 
                // Calling getIndex function
                // which will return the value
                // of idx after calculating
                getIndex(1, 0, N - 1, query.get(1));
 
                // Fetching the digit sum
                // list from the Hash Map
                List<Integer> digitSum
                    = digitSumList.get(query.get(1));
 
                // If idx is greater than
                // digitSum list size means
                // we have to return the
                // last value present in
                // the list
                if (digitSum.size() <= idx)
                    System.out.print(
                        digitSum.get(digitSum.size() - 1)
                        + " ");
 
                // Else we have to return
                // that indexed value from
                // the digitSum list
                else {
                    System.out.print(digitSum.get(idx)
                                     + " ");
                }
            }
        }
    }
 
    // Function which will return the idx
    // after adding every nodes values
    // which lies in the path from root
    // to leaf in the segment tree
    public static void getIndex(int node, int start,
                                int end, int index)
    {
        if (index >= start && index <= end) {
            if (start == end) {
                idx += tree[node];
                return;
            }
            idx += tree[node];
            int mid = (start + end) / 2;
            getIndex(node * 2, start, mid, index);
            getIndex(node * 2 + 1, mid + 1, end, index);
        }
        else
            return;
    }
 
    // Function which will update the
    // segment tree when operation 1 is in
    // act and will increment the node value
    // by 1 if it lies between the range
    // of given query
    public static void updateTree(int node, int start,
                                  int end, int l, int r)
    {
        if (l > end || start > r)
            return;
 
        if (l <= start && end <= r) {
            tree[node]++;
            return;
        }
        else {
            int mid = (start + end) / 2;
            updateTree(node * 2, start, mid, l, r);
            updateTree(node * 2 + 1, mid + 1, end, l, r);
        }
    }
 
    // Function which will build the
    // segment tree and initialize every
    // node with the value 0
    public static void buildTree(int node, int start,
                                 int end)
    {
        if (start == end) {
            tree[node] = 0;
            return;
        }
 
        int mid = (start + end) / 2;
        int left = node * 2;
        int right = (node * 2) + 1;
        buildTree(left, start, mid);
        buildTree(right, mid + 1, end);
        tree[node] = 0;
    }
 
    // Function which will return the
    // digit sum of an integer n
    public static int getSum(int n)
    {
        int sum = 0;
 
        while (n != 0) {
            sum = sum + n % 10;
            n = n / 10;
        }
 
        return sum;
    }
}


Python3




# Python3 Algorithm for the above approach
 
# Function which will return the
# digit sum of an integer n
 
 
def getSum(n):
    sum = 0
    while n != 0:
        sum = sum + n % 10
        n = n // 10
    return sum
 
 
# Function which will build the
# segment tree and initialize every
# node with the value 0
def buildTree(node, start, end, tree):
    if start == end:
        tree[node] = 0
        return
    mid = (start + end) // 2
    left = node * 2
    right = (node * 2) + 1
    buildTree(left, start, mid, tree)
    buildTree(right, mid + 1, end, tree)
    tree[node] = 0
 
 
# Function which will update the
# segment tree when operation 1 is in
# act and will increment the node value
# by 1 if it lies between the range
# of given query
def updateTree(node, start, end, l, r, tree):
    if l > end or start > r:
        return
    if l <= start and end <= r:
        tree[node] += 1
        return
    mid = (start + end) // 2
    updateTree(node * 2, start, mid, l, r, tree)
    updateTree(node * 2 + 1, mid + 1, end, l, r, tree)
 
# Function which will return the idx
# after adding every nodes values
# which lies in the path from root
# to leaf in the segment tree
 
 
def getIndex(node, start, end, index, tree):
    global idx
    if index >= start and index <= end:
        if start == end:
            idx += tree[node]
            return
        idx += tree[node]
        mid = (start + end) // 2
        getIndex(node * 2, start, mid, index, tree)
        getIndex(node * 2 + 1, mid + 1, end, index, tree)
    else:
        return
 
# Function which will update the
# array and will print the values
# for asked queries
 
 
def updateAndPrint(arr, N, queries, Q):
 
    # Map which will be used to
    # store the list of digit sum of
    # the array elements
    digitSumList = {}
    for i in range(N):
        digitSum = []
        x = arr[i]
        digitSum.append(x)
 
        # Finding and adding the
        # digit sum while x > 9
        while x > 9:
            x = getSum(x)
            digitSum.append(x)
 
        # Adding the list in the
        # Hash Map mapped with the
        # index value
        digitSumList[i] = digitSum
    tree = [0] * 20005
 
    # Calling the build Function
    # which will construct the segment
    # tree with initial value 0 in
    # the nodes
    buildTree(1, 0, N - 1, tree)
 
    # Traversing the query
    for i in range(Q):
        query = queries[i]
 
        # If the first value is 1,
        # which means we have to apply
        # 1st operation
        if query[0] == 1:
 
            # Calling the update function
            # of the segment tree
            updateTree(1, 0, N - 1, query[1], query[2], tree)
 
        # Else 2nd operation
        # comes in act
        else:
 
            # Finding idx value which
            # will be used to fetch the
            # digit sum from the list
            global idx
            idx = 0
 
            # Calling getIndex function
            # which will return the value
            # of idx after calculating
            getIndex(1, 0, N - 1, query[1], tree)
 
            # Fetching the digit sum
            # list from the Hash Map
            digitSum = digitSumList[query[1]]
 
            # If idx is greater than
            # digitSum list size means
            # we have to return the
            # last value present in
            # the list
            if len(digitSum) <= idx:
                print(digitSum[len(digitSum) - 1], end=' ')
 
            # Else we have to return
            # that indexed value from
            # the digitSum list
            else:
                print(digitSum[idx], end=' ')
 
 
# Driver Code
if __name__ == "__main__":
    N = 5
    arr = [1, 420, 69, 1434, 2023]
    Q = 8
    queries = [[1, 1, 2], [2, 1], [2, 2], [
        2, 3], [1, 1, 4], [2, 0], [2, 2], [2, 4]]
 
    # Function call
    updateAndPrint(arr, N, queries, Q)
# This code is contributed by Prajwal Kandeakar


C#




// C# Algorithm for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
  // Initializing a global segment tree
  static int[] tree = new int[20005];
 
  // Initializing a global index variable
  static int idx;
 
  // Function which will return the
  // digit sum of an integer n
  static int getSum(int n)
  {
    int sum = 0;
    while (n != 0) {
      sum = sum + n % 10;
      n = n / 10;
    }
    return sum;
  }
 
  // Function which will build the
  // segment tree and initialize every
  // node with the value 0
  static void buildTree(int node, int start, int end)
  {
    if (start == end) {
      tree[node] = 0;
      return;
    }
    int mid = (start + end) / 2;
    int left = node * 2;
    int right = (node * 2) + 1;
    buildTree(left, start, mid);
    buildTree(right, mid + 1, end);
    tree[node] = 0;
  }
 
  // Function which will update the
  // segment tree when operation 1 is in
  // act and will increment the node value
  // by 1 if it lies between the range
  // of given query
  static void updateTree(int node, int start, int end,
                         int l, int r)
  {
    if (l > end || start > r)
      return;
    if (l <= start && end <= r) {
      tree[node]++;
      return;
    }
    int mid = (start + end) / 2;
    updateTree(node * 2, start, mid, l, r);
    updateTree(node * 2 + 1, mid + 1, end, l, r);
  }
 
  // Function which will return the idx
  // after adding every nodes values
  // which lies in the path from root
  // to leaf in the segment tree
  static void getIndex(int node, int start, int end,
                       int index)
  {
    if (index >= start && index <= end) {
      if (start == end) {
        idx += tree[node];
        return;
      }
      idx += tree[node];
      int mid = (start + end) / 2;
      getIndex(node * 2, start, mid, index);
      getIndex(node * 2 + 1, mid + 1, end, index);
    }
    else
      return;
  }
 
  // Function which will update the
  // array and will print the values
  // for asked queries
  static void updateAndPrint(int[] arr, int N,
                             List<List<int> > queries,
                             int Q)
  {
 
    // Map which will be used to
    // store the list of digit sum of
    // the array elements
    Dictionary<int, List<int> > digitSumList
      = new Dictionary<int, List<int> >();
    for (int i = 0; i < N; i++) {
      List<int> digitSum = new List<int>();
      int x = arr[i];
 
      // Finding and adding the
      // digit sum while x > 9
      digitSum.Add(x);
      while (x > 9) {
        x = getSum(x);
        digitSum.Add(x);
      }
 
      // Adding the list in the
      // Hash Map mapped with the
      // index value
      digitSumList[i] = digitSum;
    }
 
    // Calling the build Function
    // which will construct the segment
    // tree with initial value 0 in
    // the nodes
    buildTree(1, 0, N - 1);
 
    // Traversing the query
    for (int i = 0; i < Q; i++) {
      List<int> query = queries[i];
 
      // If the first value is 1,
      // which means we have to apply
      // 1st operation
      if (query[0] == 1) {
 
        // Calling the update function
        // of the segment tree
        updateTree(1, 0, N - 1, query[1], query[2]);
      }
 
      // Else 2nd operation
      // comes in act
      else {
 
        // Finding idx value which
        // will be used to fetch the
        // digit sum from the list
        idx = 0;
 
        // Calling getIndex function
        // which will return the value
        // of idx after calculating
        getIndex(1, 0, N - 1, query[1]);
 
        // Fetching the digit sum
        // list from the Hash Map
        List<int> digitSum = digitSumList[query[1]];
 
        // If idx is greater than
        // digitSum list size means
        // we have to return the
        // last value present in
        // the list
        if (digitSum.Count <= idx)
          Console.Write(
          digitSum[digitSum.Count - 1] + " ");
 
        // Else we have to return
        // that indexed value from
        // the digitSum list
        else {
          Console.Write(digitSum[idx] + " ");
        }
      }
    }
  }
 
  // Driver Code
  static public void Main(string[] args)
  {
    int N = 5;
    int[] arr = { 1, 420, 69, 1434, 2023 };
    int Q = 8;
    List<List<int> > queries = new List<List<int> >();
    List<int> al = new List<int>();
    al.Add(1);
    al.Add(1);
    al.Add(2);
    queries.Add(al);
    al = new List<int>();
    al.Add(2);
    al.Add(1);
    queries.Add(al);
    al = new List<int>();
    al.Add(2);
    al.Add(2);
    queries.Add(al);
    al = new List<int>();
    al.Add(2);
    al.Add(3);
    queries.Add(al);
    al = new List<int>();
    al.Add(1);
    al.Add(1);
    al.Add(4);
    queries.Add(al);
    al = new List<int>();
    al.Add(2);
    al.Add(0);
    queries.Add(al);
    al = new List<int>();
    al.Add(2);
    al.Add(2);
    queries.Add(al);
    al = new List<int>();
    al.Add(2);
    al.Add(4);
    queries.Add(al);
 
    // Function call
    updateAndPrint(arr, N, queries, Q);
  }
}
 
// This code is contributed by prasad264


Javascript




// JavaScript Algorithm for the above approach
 
// Initializing a global segment tree
let tree = new Array(20005);
 
// Initializing a global index variable
let idx;
 
// Function which will return the
// digit sum of an integer n
function getSum(n) {
  let sum = 0;
  while (n !== 0) {
    sum = sum + (n % 10);
    n = Math.floor(n / 10);
  }
  return sum;
}
 
// Function which will build the
// segment tree and initialize every
// node with the value 0
function buildTree(node, start, end) {
  if (start === end) {
    tree[node] = 0;
    return;
  }
  let mid = Math.floor((start + end) / 2);
  let left = node * 2;
  let right = (node * 2) + 1;
  buildTree(left, start, mid);
  buildTree(right, mid + 1, end);
  tree[node] = 0;
}
 
// Function which will update the
// segment tree when operation 1 is in
// act and will increment the node value
// by 1 if it lies between the range
// of given query
function updateTree(node, start, end, l, r) {
  if (l > end || start > r) {
    return;
  }
  if (l <= start && end <= r) {
    tree[node]++;
    return;
  }
  let mid = Math.floor((start + end) / 2);
  updateTree(node * 2, start, mid, l, r);
  updateTree(node * 2 + 1, mid + 1, end, l, r);
}
 
// Function which will return the idx
// after adding every nodes values
// which lies in the path from root
// to leaf in the segment tree
function getIndex(node, start, end, index) {
  if (index >= start && index <= end) {
    if (start === end) {
      idx += tree[node];
      return;
    }
    idx += tree[node];
    let mid = Math.floor((start + end) / 2);
    getIndex(node * 2, start, mid, index);
    getIndex(node * 2 + 1, mid + 1, end, index);
  } else {
    return;
  }
}
 
// Function which will update the
// array and will print the values
// for asked queries
function updateAndPrint(arr, N, queries, Q) {
   // Map which will be used to
    // store the list of digit sum of
    // the array elements
  let digitSumList = new Map();
  let result = "";
  for (let i = 0; i < N; i++) {
    let digitSum = [];
    let x = arr[i];
     
        // Finding and adding the
        // digit sum while x > 9
    digitSum.push(x);
    while (x > 9) {
      x = getSum(x);
      digitSum.push(x);
    }
     
        // Adding the list in the
        // Hash Map mapped with the
        // index value
    digitSumList.set(i, digitSum);
  }
   
    // Calling the build Function
    // which will construct the segment
    // tree with initial value 0 in
    // the nodes
  buildTree(1, 0, N - 1);
   
  // Traversing the query
  for (let i = 0; i < Q; i++) {
    let query = queries[i];
     
       // If the first value is 1,
        // which means we have to apply
        // 1st operation
    if (query[0] === 1) {
      // Calling the update function
      // of the segment tree
      updateTree(1, 0, N - 1, query[1], query[2]);
    }
     
    // Else 2nd operation
    // comes in act
    else {
       
      // Finding idx value which
      // will be used to fetch the
      // digit sum from the list
      idx = 0;
       
      // Calling getIndex function
       // which will return the value
      // of idx after calculating
      getIndex(1, 0, N - 1, query[1]);
       
      // Fetching the digit sum
      // list from the Hash Map
      let digitSum = digitSumList.get(query[1]);
       
            // If idx is greater than
            // digitSum list size means
            // we have to return the
            // last value present in
            // the list
      if (digitSum.length <= idx) {
        result += digitSum[digitSum.length - 1] + " ";
      }
       
           // Else we have to return
            // that indexed value from
            // the digitSum list
      else {
        result += digitSum[idx] + " ";
      }
    }
  }
  process.stdout.write(result);
}
 
// Driver Code
let N = 5;
let arr = [1, 420, 69, 1434, 2023];
let Q = 8;
let queries = [
  [1, 1, 2],
  [2, 1],
  [2, 2],
  [2, 3],
  [1, 1, 4],
  [2, 0],
  [2, 2],
  [2, 4],
];
 
// Function call
updateAndPrint(arr, N, queries, Q);
 
// This code is contributed by rutikbhosale


Output

6 15 1434 1 6 7 

Time Complexity: O(N) + O(Q * log(4*N))
Auxiliary Space: O(4 * N)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads