Skip to content
geeksforgeeks
  • Tutorials
    • Python
    • Java
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
    • Practice Coding Problems
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • DSA Tutorial
  • Data Structures
  • Algorithms
  • Array
  • Strings
  • Linked List
  • Stack
  • Queue
  • Tree
  • Graph
  • Searching
  • Sorting
  • Recursion
  • Dynamic Programming
  • Binary Tree
  • Binary Search Tree
  • Heap
  • Hashing
  • Divide & Conquer
  • Mathematical
  • Geometric
  • Bitwise
  • Greedy
  • Backtracking
  • Branch and Bound
  • Matrix
  • Pattern Searching
  • Randomized
Open In App
Next Article:
Lazy Propagation in Segment Tree | Set 2
Next article icon

Lazy Propagation in Segment Tree

Last Updated : 25 Apr, 2023
Comments
Improve
Suggest changes
Like Article
Like
Report

Segment tree is introduced in previous post with an example of range sum problem. We have used the same "Sum of given Range" problem to explain Lazy propagation 
 


How does update work in Simple Segment Tree? 
In the previous post, update function was called to update only a single value in array. Please note that a single value update in array may cause multiple updates in Segment Tree as there may be many segment tree nodes that have a single array element in their ranges.
Below is simple logic used in previous post. 
1) Start with root of segment tree. 
2) If array index to be updated is not in current node's range, then return 
3) Else update current node and recur for children.
Below is code taken from previous post. 
 

CPP
/* A recursive function to update the nodes which have the given    index in their range. The following are parameters     tree[] --> segment tree     si     -->  index of current node in segment tree.                 Initial value is passed as 0.     ss and se --> Starting and ending indexes of array elements                    covered under this node of segment tree.                   Initial values passed as 0 and n-1.     i    --> index of the element to be updated. This index              is in input array.    diff --> Value to be added to all nodes which have array             index i in range */ void updateValueUtil(int tree[], int ss, int se, int i,                       int diff, int si) {     // Base Case: If the input index lies outside the range     // of this segment     if (i < ss || i > se)         return;       // If the input index is in range of this node, then     // update the value of the node and its children     st[si] = st[si] + diff;     if (se != ss)     {         int mid = getMid(ss, se);         updateValueUtil(st, ss, mid, i, diff, 2*si + 1);         updateValueUtil(st, mid+1, se, i, diff, 2*si + 2);     } } 
JavaScript
/* A recursive function to update the nodes which have the given    index in their range. The following are parameters     tree[] --> segment tree     si     -->  index of current node in segment tree.                 Initial value is passed as 0.     ss and se --> Starting and ending indexes of array elements                    covered under this node of segment tree.                   Initial values passed as 0 and n-1.     i    --> index of the element to be updated. This index              is in input array.    diff --> Value to be added to all nodes which have array             index i in range */ function updateValueUtil(tree, ss, se, i, diff, si) {     // Base Case: If the input index lies outside the range     // of this segment     if (i < ss || i > se)         return;       // If the input index is in range of this node, then     // update the value of the node and its children     st[si] = st[si] + diff;     if (se != ss)     {         let mid = getMid(ss, se);         updateValueUtil(st, ss, mid, i, diff, 2*si + 1);         updateValueUtil(st, mid+1, se, i, diff, 2*si + 2);     } }  // The code is contributed by Arushi jindal.  
Java
/* A recursive function to update the nodes which have the given    index in their range. The following are parameters     tree[] --> segment tree     si     -->  index of current node in segment tree.                 Initial value is passed as 0.     ss and se --> Starting and ending indexes of array elements                    covered under this node of segment tree.                   Initial values passed as 0 and n-1.     i    --> index of the element to be updated. This index              is in input array.    diff --> Value to be added to all nodes which have array             index i in range */ public static void updateValueUtil(int[] tree, int ss, int se, int i,  int diff, int si) {     // Base Case: If the input index lies outside the range     // of this segment     if (i < ss || i > se)         return;       // If the input index is in range of this node, then     // update the value of the node and its children     st[si] = st[si] + diff;     if (se != ss)     {         int mid = getMid(ss, se);         updateValueUtil(st, ss, mid, i, diff, 2*si + 1);         updateValueUtil(st, mid+1, se, i, diff, 2*si + 2);     } }  // The code is contrbuted by Arushi Jindal.  
Python3
# /* A recursive function to update the nodes which have the given #    index in their range. The following are parameters #     tree[] --> segment tree #     si     -->  index of current node in segment tree. #                 Initial value is passed as 0. #     ss and se --> Starting and ending indexes of array elements  #                   covered under this node of segment tree. #                   Initial values passed as 0 and n-1. #     i    --> index of the element to be updated. This index  #             is in input array. #    diff --> Value to be added to all nodes which have array #             index i in range */ def updateValueUtil(tree, ss, se, i, diff, si):          # Base Case: If the input index lies outside the range     # of this segment     if i < ss or i > se:         return       # If the input index is in range of this node, then     # update the value of the node and its children     st[si] = st[si] + diff     if se != ss:         mid = getMid(ss, se)         updateValueUtil(st, ss, mid, i, diff, 2*si + 1)         updateValueUtil(st, mid+1, se, i, diff, 2*si + 2)  # The code is contributed by Arushi jindal.  
C#
/* A recursive function to update the nodes which have the given    index in their range. The following are parameters     tree[] --> segment tree     si     -->  index of current node in segment tree.                 Initial value is passed as 0.     ss and se --> Starting and ending indexes of array elements                    covered under this node of segment tree.                   Initial values passed as 0 and n-1.     i    --> index of the element to be updated. This index              is in input array.    diff --> Value to be added to all nodes which have array             index i in range */ public static void updateValueUtil(int[] tree, int ss, int se, int i,  int diff, int si) {     // Base Case: If the input index lies outside the range     // of this segment     if (i < ss || i > se)         return;       // If the input index is in range of this node, then     // update the value of the node and its children     st[si] = st[si] + diff;     if (se != ss)     {         int mid = getMid(ss, se);         updateValueUtil(st, ss, mid, i, diff, 2*si + 1);         updateValueUtil(st, mid+1, se, i, diff, 2*si + 2);     } }  // The code is contrbuted by Arushi Jindal.  

What if there are updates on a range of array indexes? 
For example add 10 to all values at indexes from 2 to 7 in array. The above update has to be called for every index from 2 to 7. We can avoid multiple calls by writing a function updateRange() that updates nodes accordingly.
 

CPP
/* Function to update segment tree for range update in input array.     si -> index of current node in segment tree     ss and se -> Starting and ending indexes of elements for                 which current nodes stores sum.     us and ue -> starting and ending indexes of update query     diff -> which we need to add in the range us to ue */ void updateRangeUtil(int si, int ss, int se, int us, int ue,                      int diff) {     // out of range     if (ss > se || ss > ue || se < us)         return;      // Current node is a leaf node     if (ss == se) {         // Add the difference to current node         tree[si] += diff;         return;     }      // If not a leaf node, recur for children.     int mid = (ss + se) / 2;     updateRangeUtil(si * 2 + 1, ss, mid, us, ue, diff);     updateRangeUtil(si * 2 + 2, mid + 1, se, us, ue, diff);      // Use the result of children calls to update this     // node     tree[si] = tree[si * 2 + 1] + tree[si * 2 + 2]; } 
Java
void updateRangeUtil(int si, int ss, int se, int us, int ue,                      int diff) {      scss Copy code         // out of range         if (ss > se || ss > ue || se < us) return;      // Current node is a leaf node     if (ss == se) {         // Add the difference to current node         tree[si] += diff;         return;     }      // If not a leaf node, recur for children.     int mid = (ss + se) / 2;     updateRangeUtil(si * 2 + 1, ss, mid, us, ue, diff);     updateRangeUtil(si * 2 + 2, mid + 1, se, us, ue, diff);      // Use the result of children calls to update this     // node     tree[si] = tree[si * 2 + 1] + tree[si * 2 + 2]; } 
Python3
# Python   def updateRangeUtil(si, ss, se, us, ue, diff):     # out of range     if (ss > se or ss > ue or se < us):         return      # Current node is a leaf node     if (ss == se):         # Add the difference to current node         tree[si] += diff         return      # If not a leaf node, recur for children.     mid = (ss + se) // 2     updateRangeUtil(si * 2 + 1, ss, mid, us, ue, diff)     updateRangeUtil(si * 2 + 2, mid + 1, se, us, ue, diff)      # Use the result of children calls to update this     # node     tree[si] = tree[si * 2 + 1] + tree[si * 2 + 2] 
C#
/* Function to update segment tree for range update in input array.     si -> index of current node in segment tree     ss and se -> Starting and ending indexes of elements for                 which current nodes stores sum.     us and ue -> starting and ending indexes of update query     diff -> which we need to add in the range us to ue */ void UpdateRangeUtil(int si, int ss, int se, int us, int ue,                      int diff) {     // out of range     if (ss > se || ss > ue || se < us)         return;      // Current node is a leaf node     if (ss == se) {         // Add the difference to current node         tree[si] += diff;         return;     }      // If not a leaf node, recur for children.     int mid = (ss + se) / 2;     UpdateRangeUtil(si * 2 + 1, ss, mid, us, ue, diff);     UpdateRangeUtil(si * 2 + 2, mid + 1, se, us, ue, diff);      // Use the result of children calls to update this node     tree[si] = tree[si * 2 + 1] + tree[si * 2 + 2]; } 
JavaScript
/* Function to update segment tree for range update in input array.     si -> index of current node in segment tree     ss and se -> Starting and ending indexes of elements for                 which current nodes stores sum.     us and ue -> starting and ending indexes of update query     diff -> which we need to add in the range us to ue */ function updateRangeUtil(si, ss, se, us, ue, diff) {     // out of range     if (ss > se || ss > ue || se < us)         return;      // Current node is a leaf node     if (ss == se) {         // Add the difference to current node         tree[si] += diff;         return;     }      // If not a leaf node, recur for children.     let mid = Math.floor((ss + se) / 2);     updateRangeUtil(si * 2 + 1, ss, mid, us, ue, diff);     updateRangeUtil(si * 2 + 2, mid + 1, se, us, ue, diff);      // Use the result of children calls to update this     // node     tree[si] = tree[si * 2 + 1] + tree[si * 2 + 2]; }  // The code is contributed by Arushii Goel.  

Lazy Propagation - An optimization to make range updates faster
When there are many updates and updates are done on a range, we can postpone some updates (avoid recursive calls in update) and do those updates only when required.
Please remember that a node in segment tree stores or represents result of a query for a range of indexes. And if this node's range lies within the update operation range, then all descendants of the node must also be updated. For example consider the node with value 27 in above diagram, this node stores sum of values at indexes from 3 to 5. If our update query is for range 2 to 5, then we need to update this node and all descendants of this node. With Lazy propagation, we update only node with value 27 and postpone updates to its children by storing this update information in separate nodes called lazy nodes or values. We create an array lazy[] which represents lazy node. Size of lazy[] is same as array that represents segment tree, which is tree[] in below code.
The idea is to initialize all elements of lazy[] as 0. A value 0 in lazy[i] indicates that there are no pending updates on node i in segment tree. A non-zero value of lazy[i] means that this amount needs to be added to node i in segment tree before making any query to the node.
Below is modified update method. 

// To update segment tree for change in array // values at array indexes from us to ue. updateRange(us, ue) 1) If current segment tree node has any pending    update, then first add that pending update to    current node. 2) If current node's range lies completely in     update query range. ....a) Update current node ....b) Postpone updates to children by setting         lazy value for children nodes. 3) If current node's range overlaps with update     range, follow the same approach as above simple    update. ...a) Recur for left and right children. ...b) Update current node using results of left        and right calls.


Is there any change in Query Function also? 
Since we have changed update to postpone its operations, there may be problems if a query is made to a node that is yet to be updated. So we need to update our query method also which is getSumUtil in previous post. The getSumUtil() now first checks if there is a pending update and if there is, then updates the node. Once it makes sure that pending update is done, it works same as the previous getSumUtil().
Below are programs to demonstrate working of Lazy Propagation.

C++
// Program to show segment tree to demonstrate lazy // propagation #include <iostream> using namespace std; #define MAX 1000  // Ideally, we should not use global variables and large // constant-sized arrays, we have done it here for simplicity. int tree[MAX] = {0};  // To store segment tree int lazy[MAX] = {0};  // To store pending updates  /*  si -> index of current node in segment tree     ss and se -> Starting and ending indexes of elements for                  which current nodes stores sum.     us and ue -> starting and ending indexes of update query     diff -> which we need to add in the range us to ue */ void updateRangeUtil(int si, int ss, int se, int us,                      int ue, int diff) {     // If lazy value is non-zero for current node of segment     // tree, then there are some pending updates. So we need     // to make sure that the pending updates are done before     // making new updates. Because this value may be used by     // parent after recursive calls (See last line of this     // function)     if (lazy[si] != 0)     {         // Make pending updates using value stored in lazy         // nodes         tree[si] += (se-ss+1)*lazy[si];          // checking if it is not leaf node because if         // it is leaf node then we cannot go further         if (ss != se)         {             // We can postpone updating children we don't             // need their new values now.             // Since we are not yet updating children of si,             // we need to set lazy flags for the children             lazy[si*2 + 1]   += lazy[si];             lazy[si*2 + 2]   += lazy[si];         }          // Set the lazy value for current node as 0 as it         // has been updated         lazy[si] = 0;     }      // out of range     if (ss>se || ss>ue || se<us)         return ;      // Current segment is fully in range     if (ss>=us && se<=ue)     {         // Add the difference to current node         tree[si] += (se-ss+1)*diff;          // same logic for checking leaf node or not         if (ss != se)         {             // This is where we store values in lazy nodes,             // rather than updating the segment tree itself             // Since we don't need these updated values now             // we postpone updates by storing values in lazy[]             lazy[si*2 + 1]   += diff;             lazy[si*2 + 2]   += diff;         }         return;     }      // If not completely in rang, but overlaps, recur for     // children,     int mid = (ss+se)/2;     updateRangeUtil(si*2+1, ss, mid, us, ue, diff);     updateRangeUtil(si*2+2, mid+1, se, us, ue, diff);      // And use the result of children calls to update this     // node     tree[si] = tree[si*2+1] + tree[si*2+2]; }  // Function to update a range of values in segment // tree /*  us and eu -> starting and ending indexes of update query     ue  -> ending index of update query     diff -> which we need to add in the range us to ue */ void updateRange(int n, int us, int ue, int diff) {    updateRangeUtil(0, 0, n-1, us, ue, diff); }   /*  A recursive function to get the sum of values in given     range of the array. The following are parameters for     this function.     si --> Index of current node in the segment tree.            Initially 0 is passed as root is always at'            index 0     ss & se  --> Starting and ending indexes of the                  segment represented by current node,                  i.e., tree[si]     qs & qe  --> Starting and ending indexes of query                  range */ int getSumUtil(int ss, int se, int qs, int qe, int si) {     // If lazy flag is set for current node of segment tree,     // then there are some pending updates. So we need to     // make sure that the pending updates are done before     // processing the sub sum query     if (lazy[si] != 0)     {         // Make pending updates to this node. Note that this         // node represents sum of elements in arr[ss..se] and         // all these elements must be increased by lazy[si]         tree[si] += (se-ss+1)*lazy[si];          // checking if it is not leaf node because if         // it is leaf node then we cannot go further         if (ss != se)         {             // Since we are not yet updating children os si,             // we need to set lazy values for the children             lazy[si*2+1] += lazy[si];             lazy[si*2+2] += lazy[si];         }          // unset the lazy value for current node as it has         // been updated         lazy[si] = 0;     }      // Out of range     if (ss>se || ss>qe || se<qs)         return 0;      // At this point we are sure that pending lazy updates     // are done for current node. So we can return value      // (same as it was for query in our previous post)      // If this segment lies in range     if (ss>=qs && se<=qe)         return tree[si];      // If a part of this segment overlaps with the given     // range     int mid = (ss + se)/2;     return getSumUtil(ss, mid, qs, qe, 2*si+1) +            getSumUtil(mid+1, se, qs, qe, 2*si+2); }  // Return sum of elements in range from index qs (query // start) to qe (query end).  It mainly uses getSumUtil() int getSum(int n, int qs, int qe) {     // Check for erroneous input values     if (qs < 0 || qe > n-1 || qs > qe)     {         cout <<"Invalid Input";         return -1;     }      return getSumUtil(0, n-1, qs, qe, 0); }  // A recursive function that constructs Segment Tree for //  array[ss..se]. si is index of current node in segment // tree st. void constructSTUtil(int arr[], int ss, int se, int si) {     // out of range as ss can never be greater than se     if (ss > se)         return ;      // If there is one element in array, store it in     // current node of segment tree and return     if (ss == se)     {         tree[si] = arr[ss];         return;     }      // If there are more than one elements, then recur     // for left and right subtrees and store the sum     // of values in this node     int mid = (ss + se)/2;     constructSTUtil(arr, ss, mid, si*2+1);     constructSTUtil(arr, mid+1, se, si*2+2);      tree[si] = tree[si*2 + 1] + tree[si*2 + 2]; }  /* Function to construct segment tree from given array.    This function allocates memory for segment tree and    calls constructSTUtil() to fill the allocated memory */ void constructST(int arr[], int n) {     // Fill the allocated memory st     constructSTUtil(arr, 0, n-1, 0); }   // Driver program to test above functions int main() {     int arr[] = {1, 3, 5, 7, 9, 11};     int n = sizeof(arr)/sizeof(arr[0]);      // Build segment tree from given array     constructST(arr, n);      // Print sum of values in array from index 1 to 3     cout <<"Sum of values in given range = "<<            getSum(n, 1, 3);      // Add 10 to all nodes at indexes from 1 to 5.     updateRange(n, 1, 5, 10);      // Find sum after the value is updated     cout <<"\nUpdated sum of values in given range = "<<             getSum( n, 1, 3);      return 0; }  // This code is contributed by shivanisinghss2110 
C
// Program to show segment tree to demonstrate lazy // propagation #include <stdio.h> #include <math.h> #define MAX 1000  // Ideally, we should not use global variables and large // constant-sized arrays, we have done it here for simplicity. int tree[MAX] = {0};  // To store segment tree int lazy[MAX] = {0};  // To store pending updates  /*  si -> index of current node in segment tree     ss and se -> Starting and ending indexes of elements for                  which current nodes stores sum.     us and ue -> starting and ending indexes of update query     diff -> which we need to add in the range us to ue */ void updateRangeUtil(int si, int ss, int se, int us,                      int ue, int diff) {     // If lazy value is non-zero for current node of segment     // tree, then there are some pending updates. So we need     // to make sure that the pending updates are done before     // making new updates. Because this value may be used by     // parent after recursive calls (See last line of this     // function)     if (lazy[si] != 0)     {         // Make pending updates using value stored in lazy         // nodes         tree[si] += (se-ss+1)*lazy[si];          // checking if it is not leaf node because if         // it is leaf node then we cannot go further         if (ss != se)         {             // We can postpone updating children we don't             // need their new values now.             // Since we are not yet updating children of si,             // we need to set lazy flags for the children             lazy[si*2 + 1]   += lazy[si];             lazy[si*2 + 2]   += lazy[si];         }          // Set the lazy value for current node as 0 as it         // has been updated         lazy[si] = 0;     }      // out of range     if (ss>se || ss>ue || se<us)         return ;      // Current segment is fully in range     if (ss>=us && se<=ue)     {         // Add the difference to current node         tree[si] += (se-ss+1)*diff;          // same logic for checking leaf node or not         if (ss != se)         {             // This is where we store values in lazy nodes,             // rather than updating the segment tree itself             // Since we don't need these updated values now             // we postpone updates by storing values in lazy[]             lazy[si*2 + 1]   += diff;             lazy[si*2 + 2]   += diff;         }         return;     }      // If not completely in rang, but overlaps, recur for     // children,     int mid = (ss+se)/2;     updateRangeUtil(si*2+1, ss, mid, us, ue, diff);     updateRangeUtil(si*2+2, mid+1, se, us, ue, diff);      // And use the result of children calls to update this     // node     tree[si] = tree[si*2+1] + tree[si*2+2]; }  // Function to update a range of values in segment // tree /*  us and eu -> starting and ending indexes of update query     ue  -> ending index of update query     diff -> which we need to add in the range us to ue */ void updateRange(int n, int us, int ue, int diff) {    updateRangeUtil(0, 0, n-1, us, ue, diff); }   /*  A recursive function to get the sum of values in given     range of the array. The following are parameters for     this function.     si --> Index of current node in the segment tree.            Initially 0 is passed as root is always at'            index 0     ss & se  --> Starting and ending indexes of the                  segment represented by current node,                  i.e., tree[si]     qs & qe  --> Starting and ending indexes of query                  range */ int getSumUtil(int ss, int se, int qs, int qe, int si) {     // If lazy flag is set for current node of segment tree,     // then there are some pending updates. So we need to     // make sure that the pending updates are done before     // processing the sub sum query     if (lazy[si] != 0)     {         // Make pending updates to this node. Note that this         // node represents sum of elements in arr[ss..se] and         // all these elements must be increased by lazy[si]         tree[si] += (se-ss+1)*lazy[si];          // checking if it is not leaf node because if         // it is leaf node then we cannot go further         if (ss != se)         {             // Since we are not yet updating children os si,             // we need to set lazy values for the children             lazy[si*2+1] += lazy[si];             lazy[si*2+2] += lazy[si];         }          // unset the lazy value for current node as it has         // been updated         lazy[si] = 0;     }      // Out of range     if (ss>se || ss>qe || se<qs)         return 0;      // At this point we are sure that pending lazy updates     // are done for current node. So we can return value      // (same as it was for query in our previous post)      // If this segment lies in range     if (ss>=qs && se<=qe)         return tree[si];      // If a part of this segment overlaps with the given     // range     int mid = (ss + se)/2;     return getSumUtil(ss, mid, qs, qe, 2*si+1) +            getSumUtil(mid+1, se, qs, qe, 2*si+2); }  // Return sum of elements in range from index qs (query // start) to qe (query end).  It mainly uses getSumUtil() int getSum(int n, int qs, int qe) {     // Check for erroneous input values     if (qs < 0 || qe > n-1 || qs > qe)     {         printf("Invalid Input");         return -1;     }      return getSumUtil(0, n-1, qs, qe, 0); }  // A recursive function that constructs Segment Tree for //  array[ss..se]. si is index of current node in segment // tree st. void constructSTUtil(int arr[], int ss, int se, int si) {     // out of range as ss can never be greater than se     if (ss > se)         return ;      // If there is one element in array, store it in     // current node of segment tree and return     if (ss == se)     {         tree[si] = arr[ss];         return;     }      // If there are more than one elements, then recur     // for left and right subtrees and store the sum     // of values in this node     int mid = (ss + se)/2;     constructSTUtil(arr, ss, mid, si*2+1);     constructSTUtil(arr, mid+1, se, si*2+2);      tree[si] = tree[si*2 + 1] + tree[si*2 + 2]; }  /* Function to construct segment tree from given array.    This function allocates memory for segment tree and    calls constructSTUtil() to fill the allocated memory */ void constructST(int arr[], int n) {     // Fill the allocated memory st     constructSTUtil(arr, 0, n-1, 0); }   // Driver program to test above functions int main() {     int arr[] = {1, 3, 5, 7, 9, 11};     int n = sizeof(arr)/sizeof(arr[0]);      // Build segment tree from given array     constructST(arr, n);      // Print sum of values in array from index 1 to 3     printf("Sum of values in given range = %d\n",            getSum(n, 1, 3));      // Add 10 to all nodes at indexes from 1 to 5.     updateRange(n, 1, 5, 10);      // Find sum after the value is updated     printf("Updated sum of values in given range = %d\n",             getSum( n, 1, 3));      return 0; } 
Java
// Java program to demonstrate lazy propagation in segment tree class LazySegmentTree {     final int MAX = 1000;     // Max tree size     int tree[] = new int[MAX]; // To store segment tree     int lazy[] = new int[MAX]; // To store pending updates      /* si -> index of current node in segment tree         ss and se -> Starting and ending indexes of elements for                     which current nodes stores sum.         us and eu -> starting and ending indexes of update query         ue -> ending index of update query         diff -> which we need to add in the range us to ue */     void updateRangeUtil(int si, int ss, int se, int us,                         int ue, int diff)     {         // If lazy value is non-zero for current node of segment         // tree, then there are some pending updates. So we need         // to make sure that the pending updates are done before         // making new updates. Because this value may be used by         // parent after recursive calls (See last line of this         // function)         if (lazy[si] != 0)         {             // Make pending updates using value stored in lazy             // nodes             tree[si] += (se - ss + 1) * lazy[si];              // checking if it is not leaf node because if             // it is leaf node then we cannot go further             if (ss != se)             {                 // We can postpone updating children we don't                 // need their new values now.                 // Since we are not yet updating children of si,                 // we need to set lazy flags for the children                 lazy[si * 2 + 1] += lazy[si];                 lazy[si * 2 + 2] += lazy[si];             }              // Set the lazy value for current node as 0 as it             // has been updated             lazy[si] = 0;         }          // out of range         if (ss > se || ss > ue || se < us)             return;          // Current segment is fully in range         if (ss >= us && se <= ue)         {             // Add the difference to current node             tree[si] += (se - ss + 1) * diff;              // same logic for checking leaf node or not             if (ss != se)             {                 // This is where we store values in lazy nodes,                 // rather than updating the segment tree itself                 // Since we don't need these updated values now                 // we postpone updates by storing values in lazy[]                 lazy[si * 2 + 1] += diff;                 lazy[si * 2 + 2] += diff;             }             return;         }          // If not completely in rang, but overlaps, recur for         // children,         int mid = (ss + se) / 2;         updateRangeUtil(si * 2 + 1, ss, mid, us, ue, diff);         updateRangeUtil(si * 2 + 2, mid + 1, se, us, ue, diff);          // And use the result of children calls to update this         // node         tree[si] = tree[si * 2 + 1] + tree[si * 2 + 2];     }      // Function to update a range of values in segment     // tree     /* us and eu -> starting and ending indexes of update query         ue -> ending index of update query         diff -> which we need to add in the range us to ue */     void updateRange(int n, int us, int ue, int diff) {         updateRangeUtil(0, 0, n - 1, us, ue, diff);     }      /* A recursive function to get the sum of values in given         range of the array. The following are parameters for         this function.         si --> Index of current node in the segment tree.             Initially 0 is passed as root is always at'             index 0         ss & se --> Starting and ending indexes of the                     segment represented by current node,                     i.e., tree[si]         qs & qe --> Starting and ending indexes of query                     range */     int getSumUtil(int ss, int se, int qs, int qe, int si)     {         // If lazy flag is set for current node of segment tree,         // then there are some pending updates. So we need to         // make sure that the pending updates are done before         // processing the sub sum query         if (lazy[si] != 0)         {             // Make pending updates to this node. Note that this             // node represents sum of elements in arr[ss..se] and             // all these elements must be increased by lazy[si]             tree[si] += (se - ss + 1) * lazy[si];              // checking if it is not leaf node because if             // it is leaf node then we cannot go further             if (ss != se)             {                 // Since we are not yet updating children os si,                 // we need to set lazy values for the children                 lazy[si * 2 + 1] += lazy[si];                 lazy[si * 2 + 2] += lazy[si];             }              // unset the lazy value for current node as it has             // been updated             lazy[si] = 0;         }          // Out of range         if (ss > se || ss > qe || se < qs)             return 0;          // At this point sure, pending lazy updates are done         // for current node. So we can return value (same as         // was for query in our previous post)          // If this segment lies in range         if (ss >= qs && se <= qe)             return tree[si];          // If a part of this segment overlaps with the given         // range         int mid = (ss + se) / 2;         return getSumUtil(ss, mid, qs, qe, 2 * si + 1) +             getSumUtil(mid + 1, se, qs, qe, 2 * si + 2);     }      // Return sum of elements in range from index qs (query     // start) to qe (query end). It mainly uses getSumUtil()     int getSum(int n, int qs, int qe)     {         // Check for erroneous input values         if (qs < 0 || qe > n - 1 || qs > qe)         {             System.out.println("Invalid Input");             return -1;         }          return getSumUtil(0, n - 1, qs, qe, 0);     }      /* A recursive function that constructs Segment Tree for     array[ss..se]. si is index of current node in segment     tree st. */     void constructSTUtil(int arr[], int ss, int se, int si)     {         // out of range as ss can never be greater than se         if (ss > se)             return;          /* If there is one element in array, store it in         current node of segment tree and return */         if (ss == se)         {             tree[si] = arr[ss];             return;         }          /* If there are more than one elements, then recur         for left and right subtrees and store the sum         of values in this node */         int mid = (ss + se) / 2;         constructSTUtil(arr, ss, mid, si * 2 + 1);         constructSTUtil(arr, mid + 1, se, si * 2 + 2);          tree[si] = tree[si * 2 + 1] + tree[si * 2 + 2];     }      /* Function to construct segment tree from given array.     This function allocates memory for segment tree and     calls constructSTUtil() to fill the allocated memory */     void constructST(int arr[], int n)     {         // Fill the allocated memory st         constructSTUtil(arr, 0, n - 1, 0);     }       // Driver program to test above functions     public static void main(String args[])     {         int arr[] = {1, 3, 5, 7, 9, 11};         int n = arr.length;         LazySegmentTree tree = new LazySegmentTree();          // Build segment tree from given array         tree.constructST(arr, n);          // Print sum of values in array from index 1 to 3         System.out.println("Sum of values in given range = " +                         tree.getSum(n, 1, 3));          // Add 10 to all nodes at indexes from 1 to 5.         tree.updateRange(n, 1, 5, 10);          // Find sum after the value is updated         System.out.println("Updated sum of values in given range = " +                         tree.getSum(n, 1, 3));     } } // This Code is contributed by Ankur Narain Verma 
Python3
# Python3 implementation of the approach  MAX = 1000  # Ideally, we should not use global variables  # and large constant-sized arrays, we have  # done it here for simplicity.  tree = [0] * MAX; # To store segment tree  lazy = [0] * MAX; # To store pending updates   """ si -> index of current node in segment tree      ss and se -> Starting and ending indexes of elements                  for which current nodes stores sum.      us and ue -> starting and ending indexes of update query      diff -> which we need to add in the range us to ue """ def updateRangeUtil(si, ss, se, us, ue, diff) :       # If lazy value is non-zero for current node     # of segment tree, then there are some      # pending updates. So we need to make sure      # that the pending updates are done before      # making new updates. Because this value may be      # used by parent after recursive calls      # (See last line of this function)      if (lazy[si] != 0) :                  # Make pending updates using value          # stored in lazy nodes          tree[si] += (se - ss + 1) * lazy[si];           # checking if it is not leaf node because if          # it is leaf node then we cannot go further          if (ss != se) :                      # We can postpone updating children we don't              # need their new values now.              # Since we are not yet updating children of si,              # we need to set lazy flags for the children              lazy[si * 2 + 1] += lazy[si];              lazy[si * 2 + 2] += lazy[si];                   # Set the lazy value for current node          # as 0 as it has been updated          lazy[si] = 0;           # out of range      if (ss > se or ss > ue or se < us) :         return ;       # Current segment is fully in range      if (ss >= us and se <= ue) :                  # Add the difference to current node          tree[si] += (se - ss + 1) * diff;           # same logic for checking leaf node or not          if (ss != se) :                      # This is where we store values in lazy nodes,              # rather than updating the segment tree itself              # Since we don't need these updated values now              # we postpone updates by storing values in lazy[]              lazy[si * 2 + 1] += diff;              lazy[si * 2 + 2] += diff;                   return;       # If not completely in rang, but overlaps,      # recur for children,      mid = (ss + se) // 2;      updateRangeUtil(si * 2 + 1, ss,                     mid, us, ue, diff);      updateRangeUtil(si * 2 + 2, mid + 1,                      se, us, ue, diff);       # And use the result of children calls      # to update this node      tree[si] = tree[si * 2 + 1] + \             tree[si * 2 + 2];   # Function to update a range of values  # in segment tree   ''' us and eu -> starting and ending indexes                  of update query      ue -> ending index of update query      diff -> which we need to add in the range us to ue ''' def updateRange(n, us, ue, diff) :     updateRangeUtil(0, 0, n - 1, us, ue, diff);   ''' A recursive function to get the sum of values      in given range of the array. The following are      parameters for this function.      si --> Index of current node in the segment tree.          Initially 0 is passed as root is always at'          index 0      ss & se --> Starting and ending indexes of the                  segment represented by current node,                  i.e., tree[si]      qs & qe --> Starting and ending indexes of query                  range ''' def getSumUtil(ss, se, qs, qe, si) :       # If lazy flag is set for current node      # of segment tree, then there are      # some pending updates. So we need to      # make sure that the pending updates are      # done before processing the sub sum query      if (lazy[si] != 0) :              # Make pending updates to this node.          # Note that this node represents sum of          # elements in arr[ss..se] and all these          # elements must be increased by lazy[si]          tree[si] += (se - ss + 1) * lazy[si];           # checking if it is not leaf node because if          # it is leaf node then we cannot go further          if (ss != se) :                      # Since we are not yet updating children os si,              # we need to set lazy values for the children              lazy[si * 2 + 1] += lazy[si];              lazy[si * 2 + 2] += lazy[si];           # unset the lazy value for current node          # as it has been updated          lazy[si] = 0;       # Out of range      if (ss > se or ss > qe or se < qs) :         return 0;       # At this point we are sure that      # pending lazy updates are done for      # current node. So we can return value     # (same as it was for query in our previous post)       # If this segment lies in range      if (ss >= qs and se <= qe) :         return tree[si];       # If a part of this segment overlaps      # with the given range      mid = (ss + se) // 2;      return (getSumUtil(ss, mid, qs, qe, 2 * si + 1) +             getSumUtil(mid + 1, se, qs, qe, 2 * si + 2));   # Return sum of elements in range from  # index qs (query start) to qe (query end).  # It mainly uses getSumUtil()  def getSum(n, qs, qe) :          # Check for erroneous input values      if (qs < 0 or qe > n - 1 or qs > qe) :         print("Invalid Input");          return -1;       return getSumUtil(0, n - 1, qs, qe, 0);   # A recursive function that constructs  # Segment Tree for array[ss..se].  # si is index of current node in segment  # tree st.  def constructSTUtil(arr, ss, se, si) :       # out of range as ss can never be     # greater than se      if (ss > se) :         return ;       # If there is one element in array,      # store it in current node of      # segment tree and return      if (ss == se) :              tree[si] = arr[ss];          return;           # If there are more than one elements,      # then recur for left and right subtrees      # and store the sum of values in this node      mid = (ss + se) // 2;      constructSTUtil(arr, ss, mid, si * 2 + 1);      constructSTUtil(arr, mid + 1, se, si * 2 + 2);       tree[si] = tree[si * 2 + 1] + tree[si * 2 + 2];   ''' Function to construct segment tree  from given array. This function allocates memory  for segment tree and calls constructSTUtil()  to fill the allocated memory ''' def constructST(arr, n) :           # Fill the allocated memory st      constructSTUtil(arr, 0, n - 1, 0);       # Driver Code if __name__ == "__main__" :       arr = [1, 3, 5, 7, 9, 11];      n = len(arr);       # Build segment tree from given array      constructST(arr, n);       # Print sum of values in array from index 1 to 3      print("Sum of values in given range =",                         getSum(n, 1, 3));       # Add 10 to all nodes at indexes from 1 to 5.      updateRange(n, 1, 5, 10);       # Find sum after the value is updated      print("Updated sum of values in given range =",                                 getSum( n, 1, 3));   # This code is contributed by AnkitRai01 
C#
// C# program to demonstrate lazy // propagation in segment tree  using System;  public class LazySegmentTree  {      static readonly int MAX = 1000; // Max tree size      int []tree = new int[MAX]; // To store segment tree      int []lazy = new int[MAX]; // To store pending updates       /* si -> index of current node in segment tree          ss and se -> Starting and ending indexes of elements for                      which current nodes stores sum.          us and eu -> starting and ending indexes of update query          ue -> ending index of update query          diff -> which we need to add in the range us to ue */     void updateRangeUtil(int si, int ss, int se, int us,                          int ue, int diff)      {          // If lazy value is non-zero          // for current node of segment          // tree, then there are some          // pending updates. So we need          // to make sure that the pending         // updates are done before making         // new updates. Because this          // value may be used by parent         // after recursive calls (See last          // line of this function)          if (lazy[si] != 0)          {              // Make pending updates using value              // stored in lazy nodes              tree[si] += (se - ss + 1) * lazy[si];               // checking if it is not leaf node because if              // it is leaf node then we cannot go further              if (ss != se)              {                  // We can postpone updating children                  // we don't need their new values now.                  // Since we are not yet updating children of si,                  // we need to set lazy flags for the children                  lazy[si * 2 + 1] += lazy[si];                  lazy[si * 2 + 2] += lazy[si];              }               // Set the lazy value for current node              // as 0 as it has been updated              lazy[si] = 0;          }           // out of range          if (ss > se || ss > ue || se < us)              return;           // Current segment is fully in range          if (ss >= us && se <= ue)          {              // Add the difference to current node              tree[si] += (se - ss + 1) * diff;               // same logic for checking leaf node or not              if (ss != se)              {                  // This is where we store values in lazy nodes,                  // rather than updating the segment tree itself                  // Since we don't need these updated values now                  // we postpone updates by storing values in lazy[]                  lazy[si * 2 + 1] += diff;                  lazy[si * 2 + 2] += diff;              }              return;          }           // If not completely in rang, but          // overlaps, recur for children,          int mid = (ss + se) / 2;          updateRangeUtil(si * 2 + 1, ss, mid, us, ue, diff);          updateRangeUtil(si * 2 + 2, mid + 1, se, us, ue, diff);           // And use the result of children calls to update this          // node          tree[si] = tree[si * 2 + 1] + tree[si * 2 + 2];      }       // Function to update a range of values in segment      // tree      /* us and eu -> starting and ending indexes of update query          ue -> ending index of update query          diff -> which we need to add in the range us to ue */     void updateRange(int n, int us, int ue, int diff)     {          updateRangeUtil(0, 0, n - 1, us, ue, diff);      }       /* A recursive function to get the sum of values in given          range of the array. The following are parameters for          this function.          si --> Index of current node in the segment tree.              Initially 0 is passed as root is always at'              index 0          ss & se --> Starting and ending indexes of the                      segment represented by current node,                      i.e., tree[si]          qs & qe --> Starting and ending indexes of query                      range */     int getSumUtil(int ss, int se, int qs,                             int qe, int si)      {          // If lazy flag is set for current node         // of segment tree, then there are         // some pending updates. So we need to          // make sure that the pending updates         // are done before processing         // the sub sum query          if (lazy[si] != 0)          {              // Make pending updates to this              // node. Note that this node              // represents sum of elements             // in arr[ss..se] and all these             // elements must be increased by lazy[si]              tree[si] += (se - ss + 1) * lazy[si];               // checking if it is not leaf node because if              // it is leaf node then we cannot go further              if (ss != se)              {                  // Since we are not yet                  // updating children os si,                  // we need to set lazy values                 // for the children                  lazy[si * 2 + 1] += lazy[si];                  lazy[si * 2 + 2] += lazy[si];              }               // unset the lazy value for current              // node as it has been updated              lazy[si] = 0;          }           // Out of range          if (ss > se || ss > qe || se < qs)              return 0;           // At this point sure, pending lazy updates are done          // for current node. So we can return value (same as          // was for query in our previous post)           // If this segment lies in range          if (ss >= qs && se <= qe)              return tree[si];           // If a part of this segment overlaps          // with the given range          int mid = (ss + se) / 2;          return getSumUtil(ss, mid, qs, qe, 2 * si + 1) +              getSumUtil(mid + 1, se, qs, qe, 2 * si + 2);      }       // Return sum of elements in range from index qs (query      // start) to qe (query end). It mainly uses getSumUtil()      int getSum(int n, int qs, int qe)      {          // Check for erroneous input values          if (qs < 0 || qe > n - 1 || qs > qe)          {              Console.WriteLine("Invalid Input");              return -1;          }           return getSumUtil(0, n - 1, qs, qe, 0);      }       /* A recursive function that constructs     Segment Tree for array[ss..se]. si is      index of current node in segment      tree st. */     void constructSTUtil(int []arr, int ss, int se, int si)      {          // out of range as ss can          // never be greater than se          if (ss > se)              return;           /* If there is one element in array, store it in          current node of segment tree and return */         if (ss == se)          {              tree[si] = arr[ss];              return;          }           /* If there are more than one elements, then recur          for left and right subtrees and store the sum          of values in this node */         int mid = (ss + se) / 2;          constructSTUtil(arr, ss, mid, si * 2 + 1);          constructSTUtil(arr, mid + 1, se, si * 2 + 2);           tree[si] = tree[si * 2 + 1] + tree[si * 2 + 2];      }       /* Function to construct segment tree from given array.      This function allocates memory for segment tree and      calls constructSTUtil() to fill the allocated memory */     void constructST(int []arr, int n)      {          // Fill the allocated memory st          constructSTUtil(arr, 0, n - 1, 0);      }        // Driver program to test above functions      public static void Main(String []args)      {          int []arr = {1, 3, 5, 7, 9, 11};          int n = arr.Length;          LazySegmentTree tree = new LazySegmentTree();           // Build segment tree from given array          tree.constructST(arr, n);           // Print sum of values in array from index 1 to 3          Console.WriteLine("Sum of values in given range = " +                          tree.getSum(n, 1, 3));           // Add 10 to all nodes at indexes from 1 to 5.          tree.updateRange(n, 1, 5, 10);           // Find sum after the value is updated          Console.WriteLine("Updated sum of values in given range = " +                          tree.getSum(n, 1, 3));      }  }   // This code contributed by Rajput-Ji 
JavaScript
// JS program to demonstrate lazy // propagation in segment tree const MAX = 1000;  // Ideally, we should not use global variables and large // constant-sized arrays, we have done it here for simplicity. const tree = new Array(MAX).fill(0); // To store segment tree const lazy = new Array(MAX).fill(0); // To store pending updates  /*  si -> index of current node in segment tree     ss and se -> Starting and ending indexes of elements for                  which current nodes stores sum.     us and ue -> starting and ending indexes of update query     diff -> which we need to add in the range us to ue */ function updateRangeUtil(si, ss, se, us, ue, diff) {     // If lazy value is non-zero for current node of segment     // tree, then there are some pending updates. So we need     // to make sure that the pending updates are done before     // making new updates. Because this value may be used by     // parent after recursive calls (See last line of this     // function)     if (lazy[si] != 0) {         // Make pending updates using value stored in lazy         // nodes         tree[si] += (se - ss + 1) * lazy[si];                  // checking if it is not leaf node because if         // it is leaf node then we cannot go further         if (ss != se) {                       // We can postpone updating children we don't             // need their new values now.             // Since we are not yet updating children of si,             // we need to set lazy flags for the children             lazy[si * 2 + 1] += lazy[si];             lazy[si * 2 + 2] += lazy[si];         }                  // Set the lazy value for current node as 0 as it         // has been updated         lazy[si] = 0;     }          // out of range     if (ss > se || ss > ue || se < us) {         return;     }          // Current segment is fully in range     if (ss >= us && se <= ue) {         // Add the difference to current node         tree[si] += (se - ss + 1) * diff;                  // same logic for checking leaf node or not         if (ss != se) {             // This is where we store values in lazy nodes,             // rather than updating the segment tree itself             // Since we don't need these updated values now             // we postpone updates by storing values in lazy[]             lazy[si * 2 + 1] += diff;             lazy[si * 2 + 2] += diff;         }         return;     }          // If not completely in rang, but overlaps, recur for     // children,     const mid = Math.floor((ss + se) / 2);     updateRangeUtil(si * 2 + 1, ss, mid, us, ue, diff);     updateRangeUtil(si * 2 + 2, mid + 1, se, us, ue, diff);          // And use the result of children calls to update this     // node     tree[si] = tree[si * 2 + 1] + tree[si * 2 + 2]; }  // Function to update a range of values in segment // tree /*  us and eu -> starting and ending indexes of update query     ue  -> ending index of update query     diff -> which we need to add in the range us to ue */ function updateRange(n, us, ue, diff) {     updateRangeUtil(0, 0, n - 1, us, ue, diff); }  /*  A recursive function to get the sum of values in given     range of the array. The following are parameters for     this function.     si --> Index of current node in the segment tree.            Initially 0 is passed as root is always at'            index 0     ss & se  --> Starting and ending indexes of the                  segment represented by current node,                  i.e., tree[si]     qs & qe  --> Starting and ending indexes of query                  range */ function getSumUtil(ss, se, qs, qe, si) {     // If lazy flag is set for current node of segment tree,     // then there are some pending updates. So we need to     // make sure that the pending updates are done before     // processing the sub sum query     if (lazy[si] != 0) {         // Make pending updates to this node. Note that this         // node represents sum of elements in arr[ss..se] and         // all these elements must be increased by lazy[si]         tree[si] += (se - ss + 1) * lazy[si];                  // checking if it is not leaf node because if         // it is leaf node then we cannot go further         if (ss != se) {             // Since we are not yet updating children os si,             // we need to set lazy values for the children             lazy[si * 2 + 1] += lazy[si];             lazy[si * 2 + 2] += lazy[si];         }         // unset the lazy value for current node as it has         // been updated         lazy[si] = 0;     }          // Out of range     if (ss > se || ss > qe || se < qs) {         return 0;     }          // At this point we are sure that pending lazy updates     // are done for current node. So we can return value      // (same as it was for query in our previous post)      // If this segment lies in range     if (ss >= qs && se <= qe) {         return tree[si];     }          // If a part of this segment overlaps with the given     // range     const mid = Math.floor((ss + se) / 2);     return getSumUtil(ss, mid, qs, qe, 2 * si + 1) + getSumUtil(mid + 1, se, qs, qe, 2 * si + 2); }  // Return sum of elements in range from index qs (query // start) to qe (query end).  It mainly uses getSumUtil() function getSum(n, qs, qe) {     // Check for erroneous input values     if (qs < 0 || qe > n - 1 || qs > qe) {         console.log("Invalid Input");         return -1;     }     return getSumUtil(0, n - 1, qs, qe, 0); }  // A recursive function that constructs Segment Tree for //  array[ss..se]. si is index of current node in segment // tree st. function constructSTUtil(arr, ss, se, si) {     // out of range as ss can never be greater than se     if (ss > se) {         return;     }          // If there is one element in array, store it in     // current node of segment tree and return     if (ss == se) {         tree[si] = arr[ss];         return;     }          // If there are more than one elements, then recur     // for left and right subtrees and store the sum     // of values in this node     let mid = Math.floor((ss + se) / 2);     constructSTUtil(arr, ss, mid, si * 2 + 1);     constructSTUtil(arr, mid + 1, se, si * 2 + 2);     tree[si] = tree[si * 2 + 1] + tree[si * 2 + 2]; }  /* Function to construct segment tree from given array.    This function allocates memory for segment tree and    calls constructSTUtil() to fill the allocated memory */ function constructST(arr, n) {     // Fill the allocated memory st     constructSTUtil(arr, 0, n - 1, 0); }  // Driver program to test above functions let arr = [1, 3, 5, 7, 9, 11]; let n = arr.length;  // Build segment tree from given array constructST(arr, n);  // Print sum of values in array from index 1 to 3 console.log("Sum of values in given range =", getSum(n, 1, 3));  // Add 10 to all nodes at indexes from 1 to 5. updateRange(n, 1, 5, 10);  // Find sum after the value is updated console.log("Updated sum of values in given range =", getSum(n, 1, 3)); 

Output:

Sum of values in given range = 15 Updated sum of values in given range = 45 

Time Complexity: O(n)

Auxiliary Space: O(MAX)
 

Related Topic: Segment Tree

 


Next Article
Lazy Propagation in Segment Tree | Set 2

K

kartik
Improve
Article Tags :
  • Advanced Data Structure
  • DSA
  • array-range-queries
  • Segment-Tree
Practice Tags :
  • Advanced Data Structure
  • Segment-Tree

Similar Reads

    Segment Tree
    Segment Tree is a data structure that allows efficient querying and updating of intervals or segments of an array. It is particularly useful for problems involving range queries, such as finding the sum, minimum, maximum, or any other operation over a specific range of elements in an array. The tree
    3 min read
    Segment tree meaning in DSA
    A segment tree is a data structure used to effectively query and update ranges of array members. It's typically implemented as a binary tree, with each node representing a segment or range of array elements. Segment tree Characteristics of Segment Tree:A segment tree is a binary tree with a leaf nod
    2 min read
    Introduction to Segment Trees - Data Structure and Algorithm Tutorials
    A Segment Tree is used to store information about array intervals in its nodes.It allows efficient range queries over array intervals.Along with queries, it allows efficient updates of array items.For example, we can perform a range summation of an array between the range L to R in O(Log n) while al
    15+ min read
    Persistent Segment Tree | Set 1 (Introduction)
    Prerequisite : Segment Tree Persistency in Data Structure Segment Tree is itself a great data structure that comes into play in many cases. In this post we will introduce the concept of Persistency in this data structure. Persistency, simply means to retain the changes. But obviously, retaining the
    15+ min read
    Segment tree | Efficient implementation
    Let us consider the following problem to understand Segment Trees without recursion.We have an array arr[0 . . . n-1]. We should be able to, Find the sum of elements from index l to r where 0 <= l <= r <= n-1Change the value of a specified element of the array to a new value x. We need to d
    12 min read
    Iterative Segment Tree (Range Maximum Query with Node Update)
    Given an array arr[0 . . . n-1]. The task is to perform the following operation: Find the maximum of elements from index l to r where 0 <= l <= r <= n-1.Change value of a specified element of the array to a new value x. Given i and x, change A[i] to x, 0 <= i <= n-1. Examples: Input:
    14 min read
    Range Sum and Update in Array : Segment Tree using Stack
    Given an array arr[] of N integers. The task is to do the following operations: Add a value X to all the element from index A to B where 0 ? A ? B ? N-1.Find the sum of the element from index L to R where 0 ? L ? R ? N-1 before and after the update given to the array above.Example: Input: arr[] = {1
    15+ min read
    Dynamic Segment Trees : Online Queries for Range Sum with Point Updates
    Prerequisites: Segment TreeGiven a number N which represents the size of the array initialized to 0 and Q queries to process where there are two types of queries: 1 P V: Put the value V at position P.2 L R: Output the sum of values from L to R. The task is to answer these queries. Constraints: 1 ? N
    15+ min read
    Applications, Advantages and Disadvantages of Segment Tree
    First, let us understand why we need it prior to landing on the introduction so as to get why this concept was introduced. Suppose we are given an array and we need to find out the subarray Purpose of Segment Trees: A segment tree is a data structure that deals with a range of queries over an array.
    4 min read

    Lazy Propagation

    Lazy Propagation in Segment Tree
    Segment tree is introduced in previous post with an example of range sum problem. We have used the same "Sum of given Range" problem to explain Lazy propagation   How does update work in Simple Segment Tree? In the previous post, update function was called to update only a single value in array. Ple
    15+ min read
    Lazy Propagation in Segment Tree | Set 2
    Given an array arr[] of size N. There are two types of operations: Update(l, r, x) : Increment the a[i] (l <= i <= r) with value x.Query(l, r) : Find the maximum value in the array in a range l to r (both are included).Examples: Input: arr[] = {1, 2, 3, 4, 5} Update(0, 3, 4) Query(1, 4) Output
    15+ min read
    Flipping Sign Problem | Lazy Propagation Segment Tree
    Given an array of size N. There can be multiple queries of the following types. update(l, r) : On update, flip( multiply a[i] by -1) the value of a[i] where l <= i <= r . In simple terms, change the sign of a[i] for the given range.query(l, r): On query, print the sum of the array in given ran
    15+ min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences