# Lazy Propagation in Segment Tree | Set 2

Given an array arr[] of size N. There are two types of operations:

1. Update(l, r, x) : Increment the a[i] (l <= i <= r) with value x.
2. 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: 8
After applying the update operation
in the given range with given value array becomes {5, 6, 7, 8, 5}.
Then the maximum value in the range 1 to 4 is 8.

Input: arr[] = {1, 2, 3, 4, 5}
Update(0, 0, 10)
Query(0, 4)
Output: 11

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach: A detailed explanation about the lazy propagation in the segment tree is explained previously. The only thing that needed to change in the question is to return a maximum value between two child nodes when the parent node query is called. See the code for better understanding.

Below is the implementation of the above approach:

## C++

 `// C++ implementation of the approach ` `#include ` `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 ` ` `  `// To store segment tree ` `int` `tree[MAX] = { 0 }; ` ` `  `// To store pending updates ` `int` `lazy[MAX] = { 0 }; ` ` `  `// 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] += 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] += 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 itelf ` `            ``// 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 range, 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] = max(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 ` `// a range of the array. The following are the parameters ` `// for this function ` `// si --> Index of the 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] += 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 a 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` `max(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] = max(tree[si * 2 + 1], tree[si * 2 + 2]); ` `} ` ` `  `// Function to construct a segment tree from a 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 code ` `int` `main() ` `{ ` `    ``int` `arr[] = { 1, 2, 3, 4, 5 }; ` `    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr); ` ` `  `    ``// Build segment tree from given array ` `    ``constructST(arr, n); ` ` `  `    ``// Add 4 to all nodes in index range [0, 3] ` `    ``updateRange(n, 0, 3, 4); ` ` `  `    ``// Print maximum element in index range [1, 4] ` `    ``cout << getSum(n, 1, 4); ` ` `  `    ``return` `0; ` `} `

## Java

 `// Java implementation of the approach ` ` `  `class` `GFG  ` `{ ` `     `  `static` `int` `MAX =``1000``; ` ` `  `// Ideally, we should not use global variables and large ` `// constant-sized arrays, we have done it here for simplicity ` ` `  `// To store segment tree ` `static` `int` `tree[] = ``new` `int``[MAX]; ` ` `  `// To store pending updates ` `static` `int` `lazy[] = ``new` `int``[MAX]; ` ` `  `// 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 ` `static` `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] += 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] += 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 itelf ` `            ``// 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 range, 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] = Math.max(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 ` `static` `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 ` `// a range of the array. The following are the parameters ` `// for this function ` `// si --> Index of the 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 ` `static` `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] += 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 a 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` `Math.max(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() ` `static` `int` `getSum(``int` `n, ``int` `qs, ``int` `qe) ` `{ ` `    ``// Check for erroneous input values ` `    ``if` `(qs < ``0` `|| qe > n - ``1` `|| qs > qe) ` `    ``{ ` `        ``System.out.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. ` `static` `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] = Math.max(tree[si * ``2` `+ ``1``], tree[si * ``2` `+ ``2``]); ` `} ` ` `  `// Function to construct a segment tree from a given array ` `// This function allocates memory for segment tree and ` `// calls constructSTUtil() to fill the allocated memory ` `static` `void` `constructST(``int` `arr[], ``int` `n) ` `{ ` `    ``// Fill the allocated memory st ` `    ``constructSTUtil(arr, ``0``, n - ``1``, ``0``); ` `} ` ` `  `// Driver code ` `public` `static` `void` `main(String[] args)  ` `{ ` `    ``int` `arr[] = { ``1``, ``2``, ``3``, ``4``, ``5` `}; ` `    ``int` `n = arr.length; ` ` `  `    ``// Build segment tree from given array ` `    ``constructST(arr, n); ` ` `  `    ``// Add 4 to all nodes in index range [0, 3] ` `    ``updateRange(n, ``0``, ``3``, ``4``); ` ` `  `    ``// Print maximum element in index range [1, 4] ` `    ``System.out.println(getSum(n, ``1``, ``4``)); ` `} ` `} ` ` `  `/* This code contributed by PrinciRaj1992 */`

## 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  ` ` `  `# To store segment tree  ` `tree ``=` `[``0``] ``*` `MAX``;  ` ` `  `# To store pending updates  ` `lazy ``=` `[``0``] ``*` `MAX``;  ` ` `  `# 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] ``+``=` `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] ``+``=` `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 itelf  ` `            ``# 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 range, 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] ``=` `max``(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 a given range of the array. The following  ` `# are the parameters for this function  ` `# si --> Index of the 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] ``+``=` `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 a 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` `max``(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"``, end ``=` `"");  ` `        ``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] ``=` `max``(tree[si ``*` `2` `+` `1``], tree[si ``*` `2` `+` `2``]);  ` ` `  `# Function to construct a segment tree  ` `# from a 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``, ``2``, ``3``, ``4``, ``5` `];  ` `    ``n ``=` `len``(arr) ;  ` ` `  `    ``# Build segment tree from given array  ` `    ``constructST(arr, n);  ` ` `  `    ``# Add 4 to all nodes in index range [0, 3]  ` `    ``updateRange(n, ``0``, ``3``, ``4``);  ` ` `  `    ``# Print maximum element in index range [1, 4]  ` `    ``print``(getSum(n, ``1``, ``4``));  ` ` `  `# This code is contributed by AnkitRai01 `

## C#

 `// C# implementation of the approach ` `using` `System;  ` ` `  `class` `GFG  ` `{ ` `      `  `static` `int` `MAX =1000; ` `  `  `// Ideally, we should not use global variables and large ` `// constant-sized arrays, we have done it here for simplicity ` `  `  `// To store segment tree ` `static` `int` `[]tree = ``new` `int``[MAX]; ` `  `  `// To store pending updates ` `static` `int` `[]lazy = ``new` `int``[MAX]; ` `  `  `// 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 ` `static` `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] += 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] += 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 itelf ` `            ``// 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 range, 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] = Math.Max(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 ` `static` `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 ` `// a range of the array. The following are the parameters ` `// for this function ` `// si --> Index of the 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 ` `static` `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] += 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 a 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` `Math.Max(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() ` `static` `int` `getSum(``int` `n, ``int` `qs, ``int` `qe) ` `{ ` `    ``// Check for erroneous input values ` `    ``if` `(qs < 0 || qe > n - 1 || qs > qe) ` `    ``{ ` `        ``Console.Write(``"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. ` `static` `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] = Math.Max(tree[si * 2 + 1], tree[si * 2 + 2]); ` `} ` `  `  `// Function to construct a segment tree from a given array ` `// This function allocates memory for segment tree and ` `// calls constructSTUtil() to fill the allocated memory ` `static` `void` `constructST(``int` `[]arr, ``int` `n) ` `{ ` `    ``// Fill the allocated memory st ` `    ``constructSTUtil(arr, 0, n - 1, 0); ` `} ` `  `  `// Driver code ` `public` `static` `void` `Main(String[] args)  ` `{ ` `    ``int` `[]arr = { 1, 2, 3, 4, 5 }; ` `    ``int` `n = arr.Length; ` `  `  `    ``// Build segment tree from given array ` `    ``constructST(arr, n); ` `  `  `    ``// Add 4 to all nodes in index range [0, 3] ` `    ``updateRange(n, 0, 3, 4); ` `  `  `    ``// Print maximum element in index range [1, 4] ` `    ``Console.WriteLine(getSum(n, 1, 4)); ` `} ` `} ` `// This code has been contributed by 29AjayKumar `

Output:

```8
``` My Personal Notes arrow_drop_up Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.