Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

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

  • Last Updated : 07 Jul, 2021

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)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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 substree and
    // right substree
    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 substree and
    // right substree
    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 substree and
    # right substree
    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):
   
    # Prelement 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 substree and
    // right substree
    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 substree and
    // right substree
    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)




My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!