Range Update without using Lazy Propagation and Point Query in a Segment Tree
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:
- For query of type { 1, L, R, X }, update arr[L] += X and arr[R + 1] -= X using Segment tree.
- For query of type { 2, X } Find the sum of array elements in the range [0, X] using Segment Tree and print the sum obtained.
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> |
Element at 1 is 100
Time Complexity: O(|Q| * log(N))
Auxiliary Space: O(N)
Please Login to comment...