Open in App
Not now

# Range Update Queries to XOR with 1 in a Binary Array.

• Last Updated : 24 Mar, 2023

Given a binary array arr[] of size N. The task is to answer Q queries which can be of any one type from below:
Type 1 – 1 l r : Performs bitwise xor operation on all the array elements from l to r with 1.
Type 2 – 2 l r : Returns the minimum distance between two elements with value 1 in a subarray [l, r].
Type 3 – 3 l r : Returns the maximum distance between two elements with value 1 in a subarray [l, r].
Type 4 – 4 l r : Returns the minimum distance between two elements with value 0 in a subarray [l, r].
Type 5 – 5 l r : Returns the maximum distance between two elements with value 0 in a subarray [l, r].
Examples:

Input : arr[] = {1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0}, q=5
Output : 2 2 3 2
Explanation :
query 1 : Type 2, l=3, r=7
Range 3 to 7 contains { 1, 0, 1, 0, 1 }.
So, the minimum distance between two elements with value 1 is 2.
query 2 : Type 3, l=2, r=5
Range 2 to 5 contains { 0, 1, 0, 1 }.
So, the maximum distance between two elements with value 1 is 2.
query 3 : Type 1, l=1, r=4
After update array becomes {1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0}
query 4 : Type 4, l=3, r=7
Range 3 to 7 in updated array contains { 0, 1, 1, 0, 1 }.
So, the minimum distance between two elements with value 0 is 3.
query 5 : Type 5, l=4, r=9
Range 4 to 9 contains { 1, 1, 0, 1, 0, 1 }.
So, the maximum distance between two elements with value 0 is 2.

Approach:
We will create a segment tree and use range updates with lazy propagation to solve this.

• Each node in the segment tree will have the index of leftmost 1 as well as rightmost 1, leftmost 0 as well as rightmost 0 and integers containing the maximum and minimum distance between any elements with value 1 in a subarray {l, r} as well as the maximum and minimum distance between any elements with value 0 in a subarray {l, r}.

• Now, in this segment tree we can merge left and right nodes as below:

## CPP

 `// l1 = leftmost index of 1, l0 = leftmost index of 0. ` `// r1 = rightmost index of 1, r0 = rightmost index of 0. ` `// max1 = maximum distance between two 1â€™s. ` `// max0 = maximum distance between two 0â€™s. ` `// min1 = minimum distance between two 1â€™s. ` `// min0 = minimum distance between two 0â€™s. ` `node Merge(node left, node right) ` `{ ` `    ``node cur; ` `     `  `    ``if` `left.l0 is valid ` `        ``cur.l0 = left.l0 ` `    ``else` `        ``cur.l0 = r.l0 ` `    ``// We will do this for all values ` `    ``// i.e. cur.r0, cur.l1, cur.r1, cur.l0 ` `     `  `    ``// To find the min and max difference between two 1's and 0's ` `    ``// we will take min/max value of left side, right side and  ` `    ``// difference between rightmost index of 1/0 in right node  ` `    ``// and leftmost index of 1/0 in left node respectively. ` `         `  `     ``cur.min0 = minimum of left.min0 and right.min0 ` `  `  `     ``if` `left.r0 is valid and right.l0 is valid ` `        ``cur.min0 = minimum of cur.min0 and (right.l0 - left.r0) ` `    ``// We will do this for all max/min values ` `    ``// i.e. cur.min0, cur.min1, cur.max1, cur.max0 ` `         `  `    ``return` `cur; ` `} `

## Java

 `// l1 = leftmost index of 1, l0 = leftmost index of 0. ` `// r1 = rightmost index of 1, r0 = rightmost index of 0. ` `// max1 = maximum distance between two 1â€™s. ` `// max0 = maximum distance between two 0â€™s. ` `// min1 = minimum distance between two 1â€™s. ` `// min0 = minimum distance between two 0â€™s. ` `node Merge(node left, node right) ` `{ ` `    ``node cur = ``new` `node(); ` `     `  `    ``if` `(left.l0 != ``null``) ` `        ``cur.l0 = left.l0; ` `    ``else` `        ``cur.l0 = r.l0; ` `    ``// We will do this for all values ` `    ``// i.e. cur.r0, cur.l1, cur.r1, cur.l0 ` `     `  `    ``// To find the min and max difference between two 1's and 0's ` `    ``// we will take min/max value of left side, right side and  ` `    ``// difference between rightmost index of 1/0 in right node  ` `    ``// and leftmost index of 1/0 in left node respectively. ` `         `  `     ``cur.min0 = Math.min(left.min0,right.min0); ` `  `  `     ``if` `(left.r0 != ``null` `and right.l0 != ``null``) ` `        ``cur.min0 = Math.min(cur.min0 , (right.l0 - left.r0)); ` `   `  `    ``// We will do this for all max/min values ` `    ``// i.e. cur.min0, cur.min1, cur.max1, cur.max0 ` `         `  `    ``return` `cur; ` `} ` ` `  `// This code is contributed by aadityaburujwale.`

## Python3

 `def` `Merge(left, right): ` `    ``cur ``=` `{} ` `     `  `    ``if` `left[``'l0'``]: ` `        ``cur[``'l0'``] ``=` `left[``'l0'``] ` `    ``else``: ` `        ``cur[``'l0'``] ``=` `right[``'l0'``] ` `         `  `    ``# We will do this for all values ` `    ``# i.e. cur.r0, cur.l1, cur.r1, cur.l0 ` `     `  `    ``# To find the min and max difference between two 1's and 0's ` `    ``# we will take min/max value of left side, right side and  ` `    ``# difference between rightmost index of 1/0 in right node  ` `    ``# and leftmost index of 1/0 in left node respectively. ` `    ``cur[``'min0'``] ``=` `min``(left[``'min0'``], right[``'min0'``]) ` `     `  `    ``if` `left[``'r0'``] ``and` `right[``'l0'``]: ` `        ``cur[``'min0'``] ``=` `min``(cur[``'min0'``], right[``'l0'``] ``-` `left[``'r0'``]) ` `         `  `    ``# We will do this for all max/min values ` `    ``# i.e. cur.min0, cur.min1, cur.max1, cur.max0 ` `    ``return` `cur ` `   `  `# This code is contributed by akashish__`

## C#

 `// l1 = leftmost index of 1, l0 = leftmost index of 0. ` `// r1 = rightmost index of 1, r0 = rightmost index of 0. ` `// max1 = maximum distance between two 1â€™s. ` `// max0 = maximum distance between two 0â€™s. ` `// min1 = minimum distance between two 1â€™s. ` `// min0 = minimum distance between two 0â€™s. ` `public` `Node Merge(Node left, Node right) ` `{ ` `    ``Node cur = ``new` `Node(); ` ` `  `    ``if` `(left.l0 != ``null``) ` `        ``cur.l0 = left.l0; ` `    ``else` `        ``cur.l0 = right.l0; ` `   `  `    ``// We will do this for all values ` `    ``// i.e. cur.r0, cur.l1, cur.r1, cur.l0 ` ` `  `    ``// To find the min and max difference between two 1's and 0's ` `    ``// we will take min/max value of left side, right side and  ` `    ``// difference between rightmost index of 1/0 in right node  ` `    ``// and leftmost index of 1/0 in left node respectively. ` `    ``cur.min0 = Math.Min(left.min0, right.min0); ` ` `  `    ``if` `(left.r0 != ``null` `&& right.l0 != ``null``) ` `        ``cur.min0 = Math.Min(cur.min0, (right.l0 - left.r0)); ` ` `  `    ``// We will do this for all max/min values ` `    ``// i.e. cur.min0, cur.min1, cur.max1, cur.max0 ` `    ``return` `cur; ` `} ` ` `  `// This code is contributed by akashish__ `

## Javascript

 `// l1 = leftmost index of 1, l0 = leftmost index of 0. ` `// r1 = rightmost index of 1, r0 = rightmost index of 0. ` `// max1 = maximum distance between two 1â€™s. ` `// max0 = maximum distance between two 0â€™s. ` `// min1 = minimum distance between two 1â€™s. ` `// min0 = minimum distance between two 0â€™s. ` `function` `Merge(left, right) { ` `let cur = {}; ` ` `  `if` `(left.l0) { ` `    ``cur.l0 = left.l0; ` `} ``else` `{ ` `    ``cur.l0 = right.l0; ` `} ` `// We will do this for all values ` `// i.e. cur.r0, cur.l1, cur.r1, cur.l0 ` ` `  `// To find the min and max difference between two 1's and 0's ` `// we will take min/max value of left side, right side and  ` `// difference between rightmost index of 1/0 in right node  ` `// and leftmost index of 1/0 in left node respectively. ` `     `  `cur.min0 = Math.min(left.min0, right.min0); ` ` `  `if` `(left.r0 && right.l0) { ` `    ``cur.min0 = Math.min(cur.min0, right.l0 - left.r0); ` `} ` `// We will do this for all max/min values ` `// i.e. cur.min0, cur.min1, cur.max1, cur.max0 ` `     `  `return` `cur; ` `} ` `// contributed by akashish__ `

The time and space complexity of the above code is O(1).

• To handle the range update query, we will use lazy propagation. The update query asks us to xor all the elements in the range from l to r with 1, and from observations, we know that :
```       0 xor 1 = 1
1 xor 1 = 0```
• Hence, we can observe that after this update all the 0’s will change to 1 and all the 1’s will change to 0. Thus, in our segment tree nodes, all the corresponding values for 0 and 1 will also get swapped i.e.
```       l0 and l1 will get swapped
r0 and r1 will get swapped
min0 and min1 will get swapped
max0 and max1 will get swapped```
• Then, finally to find the answer to tasks 2, 3, 4 and 5 we just need to call query function for the given range {l, r} and i order to find the answer to task 1 we need to call the range update function.

Below is the implementation of the above approach:

## CPP

 `// C++ program for the given problem ` `#include ` `using` `namespace` `std; ` ` `  `int` `lazy[100001]; ` ` `  `// Class for each node ` `// in the segment tree ` `class` `node { ` `public``: ` `    ``int` `l1, r1, l0, r0; ` `    ``int` `min0, max0, min1, max1; ` ` `  `    ``node() ` `    ``{ ` `        ``l1 = r1 = l0 = r0 = -1; ` ` `  `        ``max1 = max0 = INT_MIN; ` `        ``min1 = min0 = INT_MAX; ` `    ``} ` ` `  `} seg[100001]; ` ` `  `// A utility function for ` `// merging two nodes ` `node MergeUtil(node l, node r) ` `{ ` `    ``node x; ` ` `  `    ``x.l0 = (l.l0 != -1) ? l.l0 : r.l0; ` `    ``x.r0 = (r.r0 != -1) ? r.r0 : l.r0; ` ` `  `    ``x.l1 = (l.l1 != -1) ? l.l1 : r.l1; ` `    ``x.r1 = (r.r1 != -1) ? r.r1 : l.r1; ` ` `  `    ``x.min0 = min(l.min0, r.min0); ` `    ``if` `(l.r0 != -1 && r.l0 != -1) ` `        ``x.min0 = min(x.min0, r.l0 - l.r0); ` ` `  `    ``x.min1 = min(l.min1, r.min1); ` `    ``if` `(l.r1 != -1 && r.l1 != -1) ` `        ``x.min1 = min(x.min1, r.l1 - l.r1); ` ` `  `    ``x.max0 = max(l.max0, r.max0); ` `    ``if` `(l.l0 != -1 && r.r0 != -1) ` `        ``x.max0 = max(x.max0, r.r0 - l.l0); ` ` `  `    ``x.max1 = max(l.max1, r.max1); ` `    ``if` `(l.l1 != -1 && r.r1 != -1) ` `        ``x.max1 = max(x.max1, r.r1 - l.l1); ` ` `  `    ``return` `x; ` `} ` ` `  `// utility function ` `// for updating a node ` `node UpdateUtil(node x) ` `{ ` `    ``swap(x.l0, x.l1); ` `    ``swap(x.r0, x.r1); ` `    ``swap(x.min1, x.min0); ` `    ``swap(x.max0, x.max1); ` ` `  `    ``return` `x; ` `} ` ` `  `// A recursive function that constructs ` `// Segment Tree for given string ` `void` `Build(``int` `qs, ``int` `qe, ``int` `ind, ``int` `arr[]) ` `{ ` `    ``// If start is equal to end then ` `    ``// insert the array element ` `    ``if` `(qs == qe) { ` `        ``if` `(arr[qs] == 1) { ` `            ``seg[ind].l1 = seg[ind].r1 = qs; ` `        ``} ` `        ``else` `{ ` `            ``seg[ind].l0 = seg[ind].r0 = qs; ` `        ``} ` ` `  `        ``lazy[ind] = 0; ` `        ``return``; ` `    ``} ` `    ``int` `mid = (qs + qe) >> 1; ` ` `  `    ``// Build the segment tree ` `    ``// for range qs to mid ` `    ``Build(qs, mid, ind << 1, arr); ` ` `  `    ``// Build the segment tree ` `    ``// for range mid+1 to qe ` `    ``Build(mid + 1, qe, ind << 1 | 1, arr); ` ` `  `    ``// merge the two child nodes ` `    ``// to obtain the parent node ` `    ``seg[ind] = MergeUtil( ` `        ``seg[ind << 1], ` `        ``seg[ind << 1 | 1]); ` `} ` ` `  `// Query in a range qs to qe ` `node Query(``int` `qs, ``int` `qe, ` `           ``int` `ns, ``int` `ne, ``int` `ind) ` `{ ` `    ``if` `(lazy[ind] != 0) { ` `        ``seg[ind] = UpdateUtil(seg[ind]); ` `        ``if` `(ns != ne) { ` `            ``lazy[ind * 2] ^= lazy[ind]; ` `            ``lazy[ind * 2 + 1] ^= lazy[ind]; ` `        ``} ` `        ``lazy[ind] = 0; ` `    ``} ` ` `  `    ``node x; ` ` `  `    ``// If the range lies in this segment ` `    ``if` `(qs <= ns && qe >= ne) ` `        ``return` `seg[ind]; ` ` `  `    ``// If the range is out of the bounds ` `    ``// of this segment ` `    ``if` `(ne < qs || ns > qe || ns > ne) ` `        ``return` `x; ` ` `  `    ``// Else query for the right and left ` `    ``// child node of this subtree ` `    ``// and merge them ` `    ``int` `mid = (ns + ne) >> 1; ` ` `  `    ``node l = Query(qs, qe, ns, ` `                   ``mid, ind << 1); ` `    ``node r = Query(qs, qe, ` `                   ``mid + 1, ne, ` `                   ``ind << 1 | 1); ` ` `  `    ``x = MergeUtil(l, r); ` `    ``return` `x; ` `} ` ` `  `// range update using lazy propagation ` `void` `RangeUpdate(``int` `us, ``int` `ue, ` `                 ``int` `ns, ``int` `ne, ``int` `ind) ` `{ ` `    ``if` `(lazy[ind] != 0) { ` `        ``seg[ind] = UpdateUtil(seg[ind]); ` `        ``if` `(ns != ne) { ` `            ``lazy[ind * 2] ^= lazy[ind]; ` `            ``lazy[ind * 2 + 1] ^= lazy[ind]; ` `        ``} ` `        ``lazy[ind] = 0; ` `    ``} ` ` `  `    ``// If the range is out of the bounds ` `    ``// of this segment ` `    ``if` `(ns > ne || ns > ue || ne < us) ` `        ``return``; ` ` `  `    ``// If the range lies in this segment ` `    ``if` `(ns >= us && ne <= ue) { ` `        ``seg[ind] = UpdateUtil(seg[ind]); ` `        ``if` `(ns != ne) { ` `            ``lazy[ind * 2] ^= 1; ` `            ``lazy[ind * 2 + 1] ^= 1; ` `        ``} ` `        ``return``; ` `    ``} ` ` `  `    ``// Else query for the right and left ` `    ``// child node of this subtree ` `    ``// and merge them ` `    ``int` `mid = (ns + ne) >> 1; ` `    ``RangeUpdate(us, ue, ns, mid, ind << 1); ` `    ``RangeUpdate(us, ue, mid + 1, ne, ind << 1 | 1); ` ` `  `    ``node l = seg[ind << 1], r = seg[ind << 1 | 1]; ` `    ``seg[ind] = MergeUtil(l, r); ` `} ` ` `  `// Driver code ` `int` `main() ` `{ ` ` `  `    ``int` `arr[] = { 1, 1, 0, ` `                  ``1, 0, 1, ` `                  ``0, 1, 0, ` `                  ``1, 0, 1, ` `                  ``1, 0 }; ` `    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr[0]); ` ` `  `    ``// Build the segment tree ` `    ``Build(0, n - 1, 1, arr); ` ` `  `    ``// Query of Type 2 in the range 3 to 7 ` `    ``node ans = Query(3, 7, 0, n - 1, 1); ` `    ``cout << ans.min1 << ``"\n"``; ` ` `  `    ``// Query of Type 3 in the range 2 to 5 ` `    ``ans = Query(2, 5, 0, n - 1, 1); ` `    ``cout << ans.max1 << ``"\n"``; ` ` `  `    ``// Query of Type 1 in the range 1 to 4 ` `    ``RangeUpdate(1, 4, 0, n - 1, 1); ` ` `  `    ``// Query of Type 4 in the range 3 to 7 ` `    ``ans = Query(3, 7, 0, n - 1, 1); ` `    ``cout << ans.min0 << ``"\n"``; ` ` `  `    ``// Query of Type 5 in the range 4 to 9 ` `    ``ans = Query(4, 9, 0, n - 1, 1); ` `    ``cout << ans.max0 << ``"\n"``; ` ` `  `    ``return` `0; ` `} `

## Python3

 `# Python program for the given problem ` `from` `sys ``import` `maxsize ` `from` `typing ``import` `List` `INT_MAX ``=` `maxsize ` `INT_MIN ``=` `-``maxsize ` `lazy ``=` `[``0` `for` `_ ``in` `range``(``100001``)] ` ` `  `# Class for each node ` `# in the segment tree ` `class` `node: ` `    ``def` `__init__(``self``) ``-``> ``None``: ` `        ``self``.l1 ``=` `self``.r1 ``=` `self``.l0 ``=` `self``.r0 ``=` `-``1` `        ``self``.max0 ``=` `self``.max1 ``=` `INT_MIN ` `        ``self``.min0 ``=` `self``.min1 ``=` `INT_MAX ` ` `  `seg ``=` `[node() ``for` `_ ``in` `range``(``100001``)] ` ` `  `# A utility function for ` `# merging two nodes ` `def` `MergeUtil(l: node, r: node) ``-``> node: ` `    ``x ``=` `node() ` ` `  `    ``x.l0 ``=` `l.l0 ``if` `(l.l0 !``=` `-``1``) ``else` `r.l0 ` `    ``x.r0 ``=` `r.r0 ``if` `(r.r0 !``=` `-``1``) ``else` `l.r0 ` ` `  `    ``x.l1 ``=` `l.l1 ``if` `(l.l1 !``=` `-``1``) ``else` `r.l1 ` `    ``x.r1 ``=` `r.r1 ``if` `(r.r1 !``=` `-``1``) ``else` `l.r1 ` ` `  `    ``x.min0 ``=` `min``(l.min0, r.min0) ` `    ``if` `(l.r0 !``=` `-``1` `and` `r.l0 !``=` `-``1``): ` `        ``x.min0 ``=` `min``(x.min0, r.l0 ``-` `l.r0) ` ` `  `    ``x.min1 ``=` `min``(l.min1, r.min1) ` `    ``if` `(l.r1 !``=` `-``1` `and` `r.l1 !``=` `-``1``): ` `        ``x.min1 ``=` `min``(x.min1, r.l1 ``-` `l.r1) ` ` `  `    ``x.max0 ``=` `max``(l.max0, r.max0) ` `    ``if` `(l.l0 !``=` `-``1` `and` `r.r0 !``=` `-``1``): ` `        ``x.max0 ``=` `max``(x.max0, r.r0 ``-` `l.l0) ` ` `  `    ``x.max1 ``=` `max``(l.max1, r.max1) ` `    ``if` `(l.l1 !``=` `-``1` `and` `r.r1 !``=` `-``1``): ` `        ``x.max1 ``=` `max``(x.max1, r.r1 ``-` `l.l1) ` ` `  `    ``return` `x ` ` `  `# utility function ` `# for updating a node ` `def` `UpdateUtil(x: node) ``-``> node: ` `    ``x.l0, x.l1 ``=` `x.l1, x.l0 ` `    ``x.r0, x.r1 ``=` `x.r1, x.r0 ` `    ``x.min1, x.min0 ``=` `x.min0, x.min1 ` `    ``x.max0, x.max1 ``=` `x.max1, x.max0 ` ` `  `    ``return` `x ` ` `  `# A recursive function that constructs ` `# Segment Tree for given string ` `def` `Build(qs: ``int``, qe: ``int``, ind: ``int``, arr: ``List``[``int``]) ``-``> ``None``: ` ` `  `  ``# If start is equal to end then ` `    ``# insert the array element ` `    ``if` `(qs ``=``=` `qe): ` `        ``if` `(arr[qs] ``=``=` `1``): ` `            ``seg[ind].l1 ``=` `seg[ind].r1 ``=` `qs ` `        ``else``: ` `            ``seg[ind].l0 ``=` `seg[ind].r0 ``=` `qs ` ` `  `        ``lazy[ind] ``=` `0` `        ``return` ` `  `    ``mid ``=` `(qs ``+` `qe) >> ``1` ` `  `    ``# Build the segment tree ` `    ``# for range qs to mid ` `    ``Build(qs, mid, ind << ``1``, arr) ` ` `  `    ``# Build the segment tree ` `    ``# for range mid+1 to qe ` `    ``Build(mid ``+` `1``, qe, ind << ``1` `| ``1``, arr) ` ` `  `    ``# merge the two child nodes ` `    ``# to obtain the parent node ` `    ``seg[ind] ``=` `MergeUtil(seg[ind << ``1``], seg[ind << ``1` `| ``1``]) ` ` `  `# Query in a range qs to qe ` `def` `Query(qs: ``int``, qe: ``int``, ns: ``int``, ne: ``int``, ind: ``int``) ``-``> node: ` `    ``if` `(lazy[ind] !``=` `0``): ` `        ``seg[ind] ``=` `UpdateUtil(seg[ind]) ` `        ``if` `(ns !``=` `ne): ` `            ``lazy[ind ``*` `2``] ^``=` `lazy[ind] ` `            ``lazy[ind ``*` `2` `+` `1``] ^``=` `lazy[ind] ` `        ``lazy[ind] ``=` `0` `    ``x ``=` `node() ` ` `  `    ``# If the range lies in this segment ` `    ``if` `(qs <``=` `ns ``and` `qe >``=` `ne): ` `        ``return` `seg[ind] ` ` `  `    ``# If the range is out of the bounds ` `    ``# of this segment ` `    ``if` `(ne < qs ``or` `ns > qe ``or` `ns > ne): ` `        ``return` `x ` ` `  `    ``# Else query for the right and left ` `    ``# child node of this subtree ` `    ``# and merge them ` `    ``mid ``=` `(ns ``+` `ne) >> ``1` `    ``l ``=` `Query(qs, qe, ns, mid, ind << ``1``) ` `    ``r ``=` `Query(qs, qe, mid ``+` `1``, ne, ind << ``1` `| ``1``) ` `    ``x ``=` `MergeUtil(l, r) ` `    ``return` `x ` ` `  `# range update using lazy propagation ` `def` `RangeUpdate(us: ``int``, ue: ``int``, ns: ``int``, ne: ``int``, ind: ``int``) ``-``> ``None``: ` `    ``if` `(lazy[ind] !``=` `0``): ` `        ``seg[ind] ``=` `UpdateUtil(seg[ind]) ` `        ``if` `(ns !``=` `ne): ` `            ``lazy[ind ``*` `2``] ^``=` `lazy[ind] ` `            ``lazy[ind ``*` `2` `+` `1``] ^``=` `lazy[ind] ` `        ``lazy[ind] ``=` `0` ` `  `    ``# If the range is out of the bounds ` `    ``# of this segment ` `    ``if` `(ns > ne ``or` `ns > ue ``or` `ne < us): ` `        ``return` ` `  `    ``# If the range lies in this segment ` `    ``if` `(ns >``=` `us ``and` `ne <``=` `ue): ` `        ``seg[ind] ``=` `UpdateUtil(seg[ind]) ` `        ``if` `(ns !``=` `ne): ` `            ``lazy[ind ``*` `2``] ^``=` `1` `            ``lazy[ind ``*` `2` `+` `1``] ^``=` `1` `        ``return` ` `  `    ``# Else query for the right and left ` `    ``# child node of this subtree ` `    ``# and merge them ` `    ``mid ``=` `(ns ``+` `ne) >> ``1` `    ``RangeUpdate(us, ue, ns, mid, ind << ``1``) ` `    ``RangeUpdate(us, ue, mid ``+` `1``, ne, ind << ``1` `| ``1``) ` `    ``l ``=` `seg[ind << ``1``] ` `    ``r ``=` `seg[ind << ``1` `| ``1``] ` `    ``seg[ind] ``=` `MergeUtil(l, r) ` ` `  `# Driver code ` `if` `__name__ ``=``=` `"__main__"``: ` `    ``arr ``=` `[``1``, ``1``, ``0``, ``1``, ``0``, ``1``, ``0``, ``1``, ``0``, ``1``, ``0``, ``1``, ``1``, ``0``] ` `    ``n ``=` `len``(arr) ` ` `  `    ``# Build the segment tree ` `    ``Build(``0``, n ``-` `1``, ``1``, arr) ` ` `  `    ``# Query of Type 2 in the range 3 to 7 ` `    ``ans ``=` `Query(``3``, ``7``, ``0``, n ``-` `1``, ``1``) ` `    ``print``(ans.min1) ` ` `  `    ``# Query of Type 3 in the range 2 to 5 ` `    ``ans ``=` `Query(``2``, ``5``, ``0``, n ``-` `1``, ``1``) ` `    ``print``(ans.max1) ` ` `  `    ``# Query of Type 1 in the range 1 to 4 ` `    ``RangeUpdate(``1``, ``4``, ``0``, n ``-` `1``, ``1``) ` ` `  `    ``# Query of Type 4 in the range 3 to 7 ` `    ``ans ``=` `Query(``3``, ``7``, ``0``, n ``-` `1``, ``1``) ` `    ``print``(ans.min0) ` ` `  `    ``# Query of Type 5 in the range 4 to 9 ` `    ``ans ``=` `Query(``4``, ``9``, ``0``, n ``-` `1``, ``1``) ` `    ``print``(ans.max0) ` ` `  `# This code is contributed by sanjeev2552`

## Javascript

 ``

Output

```2
2
3
2```

Time Complexity: O(n*log(n))

Auxiliary Space: O(n)

My Personal Notes arrow_drop_up
Related Articles