Open In App

Range Update without using Lazy Propagation and Point Query in a Segment Tree

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] consisting of N 0s and a 2D array Q[][] consisting of queries of the following two types:

  • 1 L R X: Increment all the elements in the range [L, R] by X.
  • 2 X: Print elements at Xth index of the array.

Input: arr[] = { 0, 0, 0, 0, 0 }, Q[][] = { { 1, 0, 2, 100 }, { 2, 1 }, { 1, 2, 3, 200 }, { 2, 2 }, { 
4 } } 
Output: 100 300 0 
Explanation: 
Query1: Incrementing all the array elements in the range [0, 2] by 100 modifies arr[] to { 100, 100, 100, 0, 0 }. 
Query2: Print arr[1](=100) 
Query3: Incrementing all the array elements in the range [2, 3] by 200 modifies arr[] to { 100, 100, 300, 200, 0 }. 
Query4: Print arr[2](=300) 
Query5: Print arr[4](=0)

Input: arr[] = { 0, 0 }, Q[][] = { { 1, 0, 1, 100 }, { 2, 1 } } 
Output: 100

Approach: The idea is to use the concept of Segment Tree to perform queries of type 2 and the difference array to perform queries of type 1. Follow the steps below to solve the problem:

Below is the implementation of the above approach:

C++




// C++ program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to update the array elements
// at idx pos, i.e arr[pos] += X
void update(int Tree[], int idx, int s,
            int e, int pos, int X)
{
    // If current node is a
    // leaf nodes
    if (s == e) {
 
        // Update Tree[idx]
        Tree[idx] += X;
    }
 
    else {
 
        // Divide segment tree into left
        // and right subtree
        int m = (s + e) / 2;
 
        // Check if pos lies in left subtree
        if (pos <= m) {
 
            // Search pos in left subtree
            update(Tree, 2 * idx, s, m, pos, X);
        }
        else {
 
            // Search pos in right subtree
            update(Tree, 2 * idx + 1, m + 1, e,
                   pos, X);
        }
 
        // Update Tree[idx]
        Tree[idx]
            = Tree[2 * idx] + Tree[2 * idx + 1];
    }
}
 
// Function to find the sum from
// elements in the range [0, X]
int sum(int Tree[], int idx, int s,
        int e, int ql, int qr)
{
    // Check if range[ql, qr] equals
    // to range [s, e]
    if (ql == s && qr == e)
        return Tree[idx];
 
    if (ql > qr)
        return 0;
 
    // Divide segment tree into
    // left subtree and
    // right subtree
    int m = (s + e) / 2;
 
    // Return sum of elements in the range[ql, qr]
    return sum(Tree, 2 * idx, s, m, ql, min(m, qr))
           + sum(Tree, 2 * idx + 1, m + 1, e,
                 max(ql, m + 1), qr);
}
 
// Function to find Xth element
// in the array
void getElement(int Tree[], int X, int N)
{
    // Print element at index x
    cout << "Element at " << X << " is "
         << sum(Tree, 1, 0, N - 1, 0, X) << endl;
}
 
// Function to update array elements
// in the range [L, R]
void range_Update(int Tree[], int L,
                  int R, int X, int N)
{
 
    // Update arr[l] += X
    update(Tree, 1, 0, N - 1, L, X);
 
    // Update arr[R + 1] += X
    if (R + 1 < N)
        update(Tree, 1, 0, N - 1, R + 1, -X);
}
 
// Drivers Code
int main()
{
    // Size of array
    int N = 5;
 
    int Tree[4 * N + 5] = { 0 };
 
    int arr[] = { 0, 0 };
    vector<vector<int> >
        Q = { { 1, 0, 1, 100 }, { 2, 1 } };
 
    int cntQuery = Q.size();
    for (int i = 0; i < cntQuery; i++) {
 
        if (Q[i][0] == 1) {
 
            range_Update(Tree, Q[i][1],
                         Q[i][2], Q[i][3], N);
        }
        else {
 
            getElement(Tree, Q[i][1], N);
        }
    }
}


Java




// Java program to implement
// the above approach
import java.util.*;
class GFG
{
 
// Function to update the array elements
// at idx pos, i.e arr[pos] += X
static void update(int Tree[], int idx, int s,
            int e, int pos, int X)
{
   
    // If current node is a
    // leaf nodes
    if (s == e)
    {
 
        // Update Tree[idx]
        Tree[idx] += X;
    }
 
    else
    {
 
        // Divide segment tree into left
        // and right subtree
        int m = (s + e) / 2;
 
        // Check if pos lies in left subtree
        if (pos <= m)
        {
 
            // Search pos in left subtree
            update(Tree, 2 * idx, s, m, pos, X);
        }
        else
        {
 
            // Search pos in right subtree
            update(Tree, 2 * idx + 1, m + 1, e,
                   pos, X);
        }
 
        // Update Tree[idx]
        Tree[idx]
            = Tree[2 * idx] + Tree[2 * idx + 1];
    }
}
 
// Function to find the sum from
// elements in the range [0, X]
static int sum(int Tree[], int idx, int s,
        int e, int ql, int qr)
{
   
    // Check if range[ql, qr] equals
    // to range [s, e]
    if (ql == s && qr == e)
        return Tree[idx];
 
    if (ql > qr)
        return 0;
 
    // Divide segment tree into
    // left subtree and
    // right subtree
    int m = (s + e) / 2;
 
    // Return sum of elements in the range[ql, qr]
    return sum(Tree, 2 * idx, s, m, ql, Math.min(m, qr))
           + sum(Tree, 2 * idx + 1, m + 1, e,
                 Math.max(ql, m + 1), qr);
}
 
// Function to find Xth element
// in the array
static void getElement(int Tree[], int X, int N)
{
   
    // Print element at index x
    System.out.print("Element at " +  X+ " is "
         + sum(Tree, 1, 0, N - 1, 0, X) +"\n");
}
 
// Function to update array elements
// in the range [L, R]
static void range_Update(int Tree[], int L,
                  int R, int X, int N)
{
 
    // Update arr[l] += X
    update(Tree, 1, 0, N - 1, L, X);
 
    // Update arr[R + 1] += X
    if (R + 1 < N)
        update(Tree, 1, 0, N - 1, R + 1, -X);
}
 
// Drivers Code
public static void main(String[] args)
{
   
    // Size of array
    int N = 5;
    int Tree[] = new int[4 * N + 5];
    int arr[] = { 0, 0 };
    int[][]
        Q = { { 1, 0, 1, 100 }, { 2, 1 } };
    int cntQuery = Q.length;
    for (int i = 0; i < cntQuery; i++)
    {
        if (Q[i][0] == 1)
        {
            range_Update(Tree, Q[i][1],
                         Q[i][2], Q[i][3], N);
        }
        else
        {
            getElement(Tree, Q[i][1], N);
        }
    }
}
}
 
// This code is contributed by shikhasingrajput


Python3




# Python3 program to implement
# the above approach
 
# Function to update the array elements
# at idx pos, i.e arr[pos] += X
def update(Tree, idx, s, e, pos, X):
   
    # If current node is a
    # leaf nodes
    if (s == e):
 
        # Update Tree[idx]
        Tree[idx] += X
 
    else:
 
        # Divide segment tree into left
        # and right subtree
        m = (s + e) // 2
 
        # Check if pos lies in left subtree
        if (pos <= m):
 
            # Search pos in left subtree
            update(Tree, 2 * idx, s, m, pos, X)
        else:
 
            # Search pos in right subtree
            update(Tree, 2 * idx + 1, m + 1, e,pos, X)
 
        # Update Tree[idx]
        Tree[idx] = Tree[2 * idx] + Tree[2 * idx + 1]
 
# Function to find the sum from
# elements in the range [0, X]
def sum(Tree, idx, s, e, ql, qr):
   
    # Check if range[ql, qr] equals
    # to range [s, e]
    if (ql == s and qr == e):
        return Tree[idx]
 
    if (ql > qr):
        return 0
 
    # Divide segment tree into
    # left subtree and
    # right subtree
    m = (s + e) // 2
 
    # Return sum of elements in the range[ql, qr]
    return sum(Tree, 2 * idx, s, m, ql, min(m, qr))+ sum(Tree, 2 * idx + 1, m + 1, e,max(ql, m + 1), qr)
 
# Function to find Xth element
# in the array
def getElement(Tree, X, N):
   
    # Print element at index x
    print("Element at", X, "is ", sum(Tree, 1, 0, N - 1, 0, X))
 
# Function to update array elements
# in the range [L, R]
def range_Update(Tree, L, R, X, N):
 
    # Update arr[l] += X
    update(Tree, 1, 0, N - 1, L, X)
 
    # Update arr[R + 1] += X
    if (R + 1 < N):
        update(Tree, 1, 0, N - 1, R + 1, -X)
 
# Drivers Code
if __name__ == '__main__':
   
    # Size of array
    N = 5
    Tree = [0]*(4 * N + 5)
    arr = [0, 0]
    Q = [ [1, 0, 1, 100], [2, 1] ]
    cntQuery = len(Q)
    for i in range(cntQuery):
        if (Q[i][0] == 1):
            range_Update(Tree, Q[i][1], Q[i][2], Q[i][3], N)
        else:
            getElement(Tree, Q[i][1], N)
 
# This code is contributed by mohit kumar 29.


C#




// C# program to implement
// the above approach
using System;
public class GFG
{
 
  // Function to update the array elements
  // at idx pos, i.e arr[pos] += X
  static void update(int []Tree, int idx, int s,
                     int e, int pos, int X)
  {
 
    // If current node is a
    // leaf nodes
    if (s == e)
    {
 
      // Update Tree[idx]
      Tree[idx] += X;
    }
 
    else
    {
 
      // Divide segment tree into left
      // and right subtree
      int m = (s + e) / 2;
 
      // Check if pos lies in left subtree
      if (pos <= m)
      {
 
        // Search pos in left subtree
        update(Tree, 2 * idx, s, m, pos, X);
      }
      else
      {
 
        // Search pos in right subtree
        update(Tree, 2 * idx + 1, m + 1, e,
               pos, X);
      }
 
      // Update Tree[idx]
      Tree[idx]
        = Tree[2 * idx] + Tree[2 * idx + 1];
    }
  }
 
  // Function to find the sum from
  // elements in the range [0, X]
  static int sum(int []Tree, int idx, int s,
                 int e, int ql, int qr)
  {
 
    // Check if range[ql, qr] equals
    // to range [s, e]
    if (ql == s && qr == e)
      return Tree[idx];
 
    if (ql > qr)
      return 0;
 
    // Divide segment tree into
    // left subtree and
    // right subtree
    int m = (s + e) / 2;
 
    // Return sum of elements in the range[ql, qr]
    return sum(Tree, 2 * idx, s, m, ql, Math.Min(m, qr))
      + sum(Tree, 2 * idx + 1, m + 1, e,
            Math.Max(ql, m + 1), qr);
  }
 
  // Function to find Xth element
  // in the array
  static void getElement(int []Tree, int X, int N)
  {
 
    // Print element at index x
    Console.Write("Element at " +  X+ " is "
                  + sum(Tree, 1, 0, N - 1, 0, X) +"\n");
  }
 
  // Function to update array elements
  // in the range [L, R]
  static void range_Update(int []Tree, int L,
                           int R, int X, int N)
  {
 
    // Update arr[l] += X
    update(Tree, 1, 0, N - 1, L, X);
 
    // Update arr[R + 1] += X
    if (R + 1 < N)
      update(Tree, 1, 0, N - 1, R + 1, -X);
  }
 
  // Drivers Code
  public static void Main(String[] args)
  {
 
    // Size of array
    int N = 5;
    int []Tree = new int[4 * N + 5];
    int []arr = { 0, 0 };
    int[,]Q = { { 1, 0, 1, 100 }, { 2, 1, 0, 0 } };
    int cntQuery = Q.GetLength(0);
    for (int i = 0; i < cntQuery; i++)
    {
      if (Q[i, 0] == 1)
      {
        range_Update(Tree, Q[i, 1],
                     Q[i, 2], Q[i, 3], N);
      }
      else
      {
        getElement(Tree, Q[i, 1], N);
      }
    }
  }
}
 
// This code is contributed by 29AjayKumar


Javascript




<script>
 
// Javascript program to implement
// the above approach
 
// Function to update the array elements
// at idx pos, i.e arr[pos] += X
function update(Tree, idx, s, e, pos, X)
{
    // If current node is a
    // leaf nodes
    if (s == e) {
 
        // Update Tree[idx]
        Tree[idx] += X;
    }
 
    else {
 
        // Divide segment tree into left
        // and right subtree
        var m = parseInt((s + e) / 2);
 
        // Check if pos lies in left subtree
        if (pos <= m) {
 
            // Search pos in left subtree
            update(Tree, 2 * idx, s, m, pos, X);
        }
        else {
 
            // Search pos in right subtree
            update(Tree, 2 * idx + 1, m + 1, e,
                   pos, X);
        }
 
        // Update Tree[idx]
        Tree[idx]
            = Tree[2 * idx] + Tree[2 * idx + 1];
    }
}
 
// Function to find the sum from
// elements in the range [0, X]
function sum(Tree, idx, s, e, ql, qr)
{
    // Check if range[ql, qr] equals
    // to range [s, e]
    if (ql == s && qr == e)
        return Tree[idx];
 
    if (ql > qr)
        return 0;
 
    // Divide segment tree into
    // left subtree and
    // right subtree
    var m =parseInt((s + e) / 2);
 
    // Return sum of elements in the range[ql, qr]
    return sum(Tree, 2 * idx, s, m, ql, Math.min(m, qr))
           + sum(Tree, 2 * idx + 1, m + 1, e,
                 Math.max(ql, m + 1), qr);
}
 
// Function to find Xth element
// in the array
function getElement(Tree, X, N)
{
    // Print element at index x
    document.write( "Element at " + X + " is "
         + sum(Tree, 1, 0, N - 1, 0, X) );
}
 
// Function to update array elements
// in the range [L, R]
function range_Update(Tree, L, R, X, N)
{
 
    // Update arr[l] += X
    update(Tree, 1, 0, N - 1, L, X);
 
    // Update arr[R + 1] += X
    if (R + 1 < N)
        update(Tree, 1, 0, N - 1, R + 1, -X);
}
 
// Drivers Code
// Size of array
var N = 5;
var Tree = Array(4 * N + 5).fill(0);
var arr = [ 0, 0 ];
var Q = [[ 1, 0, 1, 100 ], [ 2, 1 ]];
var cntQuery = Q.length;
for (var i = 0; i < cntQuery; i++) {
    if (Q[i][0] == 1) {
        range_Update(Tree, Q[i][1],
                     Q[i][2], Q[i][3], N);
    }
    else {
        getElement(Tree, Q[i][1], N);
    }
}
 
 
</script>


Output: 

Element at 1 is 100

 

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



Last Updated : 01 Jun, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads