Related Articles
Lazy Propagation in Segment Tree | Set 2
• Difficulty Level : Medium
• Last Updated : 15 Nov, 2019

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
```

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

My Personal Notes arrow_drop_up