GeeksforGeeks App
Open App
Browser
Continue

# Array range queries to find the maximum Fibonacci number with updates

Given an array arr[] of N integers, the task is to perform the following two queries:

• maximum(start, end): Print the maximum Fibonacci number of elements in the sub-array from start to end
• update(i, x): Add x to the array element referenced by array index i, that is: arr[i] = x

Note: The below example consists of 0 based indexing.

Example:

Input: arr = [1, 3, 5, 7, 9, 11]
Query 1: Maximum (Start = 1, End = 3)
Query 2: Update (3, 8) i.e. arr[3] = 8
Output:
Maximum Fibonacci number in given range = 5
Updated Maximum Fibonacci number in given range = 8
Explanation:
In the Maximum Query, the sub-array [1…3]
has 2 Fibonacci 3 and 5 viz. {3, 5, 7}
Hence, 5 is the maximum Fibonacci number in the given range.
In the Update Query, the value at index 3 is updated
to 8, the array arr now is, [1, 3, 5, 8, 9, 11]
In Updated Maximum Query, the sub-array [1…3]
has all 3 Fibonacci numbers 3, 5 and 8 viz. [3, 5, 8]
Hence, 8 is the maximum Fibonacci number in the given range.

Simple Approach:

A simple solution is to run a loop from l to r and calculate the maximum Fibonacci number out of all the elements in a given range. To update a value, simply do arr[i] = x. The first operation takes O(N*F) time and the second operation takes O(1) time.

Below is the implementation of the above approach :

## C++14

 `// CPP code for range maximum``// query and updates``#include ``using` `namespace` `std;` `// Function to calculate the nth``// Fibonacci number``int` `fib(``int` `n)``{``    ``if` `(n <= 1)``        ``return` `n;``    ``return` `fib(n - 1) + fib(n - 2);``}` `// Function to get the maximum Fibonacci``// number in the given range``int` `getMax(``int` `arr[], ``int` `n, ``int` `l, ``int` `r)``{``    ``int` `maxFib = -1;``    ``for` `(``int` `i = l; i <= r; i++) {``        ``for` `(``int` `j = 0; j <= n; j++) {``            ``int` `fibNum = fib(j);``            ``if` `(fibNum == arr[i]) {``                ``maxFib = max(maxFib, fibNum);``                ``break``;``            ``}``            ``else` `if` `(fibNum > arr[i]) {``                ``break``;``            ``}``        ``}``    ``}``    ``return` `maxFib;``}` `// Function to update an array element``void` `updateValue(``int` `arr[], ``int` `i, ``int` `x)``{``      ``arr[i] = x;``}` `// Driver Code``int` `main()``{``    ``int` `arr[] = { 1, 3, 5, 7, 9, 11 };``    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr[0]);` `    ``// Print max of values in array``    ``// from index 1 to 3``    ``cout << ``"Maximum fibonacci number"``         ``<< ``" in given range = "` `<< getMax(arr, n, 1, 3)``         ``<< endl;` `    ``// Update: set arr[1] = 8 and update``    ``// corresponding segment tree nodes.``    ``updateValue(arr, 1, 8);` `    ``// Find max after the value is updated``    ``cout << ``"Updated Maximum Fibonacci"``         ``<< ``" number in given range = "``         ``<< getMax(arr, n, 1, 3) << endl;` `    ``return` `0;``}`

Output

```Maximum fibonacci number in given range = 5
Updated Maximum Fibonacci number in given range = 8
```

Time Complexity: O(N * F), where N is the size of the range and F is the maximum Fibonacci number in the range.
Space Complexity: O(1)

Efficient Approach :
Here, we need to perform operations in O(Log N) time so we can use Segment Tree to do both operations in O(Log N) time.
Representation of Segment trees:
1. Leaf Nodes are the elements of the input array.
2. Each internal node represents the maximum Fibonacci number of all of its child nodes or -1 if there is no Fibonacci number existing in the range.
An array representation of tree is used to represent Segment Trees. For each node at index i, the left child is at index 2*i+1, right child at index 2*i+2 and the parent is at index (i-1)/2.
Construction of Segment Tree from given array :
We start with a segment arr[0 . . . n-1], and every time we divide the current segment into two halves(if it has not yet become a segment of length 1), and then call the same procedure on both halves, and for each such segment, we store the maximum Fibonacci number value or -1 in a segment tree node. All levels of the constructed segment tree will be completely filled except the last level. Also, the tree will be a full Binary Tree because we always divide segments into two halves at every level. Since the constructed tree is always a full binary tree with n leaves, there will be n-1 internal nodes. So total nodes will be 2*n – 1. Height of the segment tree will be log2N. Since the tree is represented using array and relation between parent and child indexes must be maintained, size of memory allocated for segment tree will be 2*( 2ceil(log2n) ) – 1.
In order to check for Fibonacci numbers, we can build a hash table using dynamic programming containing all the Fibonacci numbers less than or equal to the maximum value arr can take say MAX which will be used to test a number in O(1) time.
We then do a range query on the segment tree to find out the max_set_bits for the given range and output the corresponding value.

Below is the implementation of above approach :

## CPP

 `// CPP code for range maximum query and updates``#include ``using` `namespace` `std;` `set<``int``> fibonacci;` `// A utility function to get the``// middle index of given range.``int` `getMid(``int` `s, ``int` `e)``{``    ``return` `s + (e - s) / 2;``}` `// Function to create hash table``// to check Fibonacci numbers``void` `createHash(``int` `maxElement)``{``    ``int` `prev = 0, curr = 1;``    ``fibonacci.insert(prev);``    ``fibonacci.insert(curr);` `    ``while` `(curr <= maxElement) {``        ``int` `temp = curr + prev;``        ``fibonacci.insert(temp);``        ``prev = curr;``        ``curr = temp;``    ``}``}` `/*  A recursive function to get the sum of``    ``values in given range of the array.``    ``The following are parameters for this``    ``function.` `    ``st       -> Pointer to segment tree``    ``node     -> Index of current node in``                ``the segment tree .``    ``ss & se  -> Starting and ending indexes``                ``of the segment represented``                ``by current node, i.e., st[node]``    ``l & r    -> Starting and ending indexes``                ``of range query */``int` `MaxUtil(``int``* st, ``int` `ss, ``int` `se, ``int` `l,``            ``int` `r, ``int` `node)``{``    ``// If segment of this node is completely``    ``// part of given range, then return``    ``// the max of segment``    ``if` `(l <= ss && r >= se)``        ``return` `st[node];` `    ``// If segment of this node does not``    ``// belong to given range``    ``if` `(se < l || ss > r)``        ``return` `-1;` `    ``// If segment of this node is partially``    ``// the part of given range``    ``int` `mid = getMid(ss, se);` `    ``return` `max(MaxUtil(st, ss, mid, l, r,``                       ``2 * node + 1),``               ``MaxUtil(st, mid + 1, se, l,``                       ``r, 2 * node + 2));``}` `/* A recursive function to update the nodes which``   ``have the given index in their range. The following``   ``are parameters st, ss and se are same as defined``   ``above index -> index of the element to be updated.*/``void` `updateValue(``int` `arr[], ``int``* st, ``int` `ss, ``int` `se,``                 ``int` `index, ``int` `value, ``int` `node)``{``    ``if` `(index < ss || index > se) {``        ``cout << ``"Invalid Input"` `<< endl;``        ``return``;``    ``}` `    ``if` `(ss == se) {``        ``// update value in array and in segment tree``        ``arr[index] = value;` `        ``if` `(fibonacci.find(value) != fibonacci.end())``            ``st[node] = value;``        ``else``            ``st[node] = -1;``    ``}``    ``else` `{``        ``int` `mid = getMid(ss, se);` `        ``if` `(index >= ss && index <= mid)``            ``updateValue(arr, st, ss, mid, index,``                        ``value, 2 * node + 1);``        ``else``            ``updateValue(arr, st, mid + 1, se,``                        ``index, value, 2 * node + 2);` `        ``st[node] = max(st[2 * node + 1],``                       ``st[2 * node + 2]);``    ``}``    ``return``;``}` `// Return max of elements in range from``// index l (query start) to r (query end).``int` `getMax(``int``* st, ``int` `n, ``int` `l, ``int` `r)``{``    ``// Check for erroneous input values``    ``if` `(l < 0 || r > n - 1 || l > r) {``        ``printf``(``"Invalid Input"``);``        ``return` `-1;``    ``}` `    ``return` `MaxUtil(st, 0, n - 1, l, r, 0);``}` `// A recursive function that constructs Segment``// Tree for array[ss..se]. si is index of``// current node in segment tree st``int` `constructSTUtil(``int` `arr[], ``int` `ss, ``int` `se,``                    ``int``* st, ``int` `si)``{``    ``// If there is one element in array, store``    ``// it in current node of segment tree and return``    ``if` `(ss == se) {``        ``if` `(fibonacci.find(arr[ss])``            ``!= fibonacci.end())``            ``st[si] = arr[ss];``        ``else``            ``st[si] = -1;``        ``return` `st[si];``    ``}` `    ``// If there are more than one elements, then``    ``// recur for left and right subtrees and``    ``// store the max of values in this node``    ``int` `mid = getMid(ss, se);` `    ``st[si]``        ``= max(constructSTUtil(``                  ``arr, ss, mid, st,``                  ``si * 2 + 1),``              ``constructSTUtil(``                  ``arr, mid + 1, se,``                  ``st, si * 2 + 2));` `    ``return` `st[si];``}` `/* Function to construct segment tree``   ``from given array.``   ``This function allocates memory``   ``for segment tree.*/``int``* constructST(``int` `arr[], ``int` `n)``{``    ``// Height of segment tree``    ``int` `x = (``int``)(``ceil``(log2(n)));` `    ``// Maximum size of segment tree``    ``int` `max_size = 2 * (``int``)``pow``(2, x) - 1;` `    ``// Allocate memory``    ``int``* st = ``new` `int``[max_size];` `    ``// Fill the allocated memory st``    ``constructSTUtil(arr, 0, n - 1, st, 0);` `    ``// Return the constructed segment tree``    ``return` `st;``}` `// Driver code``int` `main()``{``    ``int` `arr[] = { 1, 3, 5, 7, 9, 11 };``    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr[0]);` `    ``// find the largest node value``    ``// in the array``    ``int` `maxEle = *max_element(arr, arr + n);` `    ``// creating a set containing``    ``// all fibonacci numbers``    ``// upto the maximum data value``    ``// in the array``    ``createHash(maxEle);` `    ``// Build segment tree from given array``    ``int``* st = constructST(arr, n);` `    ``// Print max of values in array``    ``// from index 1 to 3``    ``cout << ``"Maximum fibonacci number"``         ``<< ``" in given range = "``         ``<< getMax(st, n, 1, 3) << endl;` `    ``// Update: set arr[1] = 8 and update``    ``// corresponding segment tree nodes.``    ``updateValue(arr, st, 0, n - 1, 3, 8, 0);` `    ``// Find max after the value is updated``    ``cout << ``"Updated Maximum Fibonacci"``         ``<< ``" number in given range = "``         ``<< getMax(st, n, 1, 3) << endl;` `    ``return` `0;``}`

## Java

 `// Java code for range maximum query and updates``import` `java.util.Arrays;``import` `java.util.HashSet;``import` `java.util.Set;` `class` `GFG {` `  ``static` `Set fibonacci = ``new` `HashSet<>();` `  ``// A utility function to get the``  ``// middle index of given range.``  ``static` `int` `getMid(``int` `s, ``int` `e) {``    ``return` `s + (e - s) / ``2``;``  ``}` `  ``// Function to create hash table``  ``// to check Fibonacci numbers``  ``static` `void` `createHash(``int` `maxElement) {``    ``int` `prev = ``0``, curr = ``1``;``    ``fibonacci.add(prev);``    ``fibonacci.add(curr);` `    ``while` `(curr <= maxElement) {``      ``int` `temp = curr + prev;``      ``fibonacci.add(temp);``      ``prev = curr;``      ``curr = temp;``    ``}``  ``}` `  ``/*``     ``* A recursive function to get the sum of``     ``* values in given range of the array.``     ``* The following are parameters for this function.``     ``*``     ``* st       -> Pointer to segment tree``     ``* node     -> Index of current node``     ``*             in the segment tree .``     ``* ss & se  -> Starting and ending indexes``     ``*             of the segment represented``     ``*             by current node, i.e., st[node]``     ``* l & r    -> Starting and ending indexes``     ``*             of range query``     ``*/``  ``static` `int` `MaxUtil(``int``[] st, ``int` `ss, ``int` `se,``                     ``int` `l, ``int` `r, ``int` `node)``  ``{` `    ``// If segment of this node is completely``    ``// part of given range, then return``    ``// the max of segment``    ``if` `(l <= ss && r >= se)``      ``return` `st[node];` `    ``// If segment of this node does not``    ``// belong to given range``    ``if` `(se < l || ss > r)``      ``return` `-``1``;` `    ``// If segment of this node is partially``    ``// the part of given range``    ``int` `mid = getMid(ss, se);` `    ``return` `Math.max(MaxUtil(st, ss, mid, l, r, ``2` `* node + ``1``),``                    ``MaxUtil(st, mid + ``1``, se, l, r, ``2` `* node + ``2``));``  ``}` `  ``/*``     ``* A recursive function to update the nodes which``     ``* have the given index in their range. The following``     ``* are parameters st, ss and se are same as defined``     ``* above index -> index of the element to be updated.``     ``*/``  ``static` `void` `updateValue(``int` `arr[], ``int``[] st, ``int` `ss, ``int` `se,``                          ``int` `index, ``int` `value, ``int` `node) {``    ``if` `(index < ss || index > se) {``      ``System.out.println(``"Invalid Input"``);``      ``return``;``    ``}` `    ``if` `(ss == se) {``      ``// update value in array and in segment tree``      ``arr[index] = value;` `      ``if` `(fibonacci.contains(value))``        ``st[node] = value;``      ``else``        ``st[node] = -``1``;``    ``} ``else` `{``      ``int` `mid = getMid(ss, se);` `      ``if` `(index >= ss && index <= mid)``        ``updateValue(arr, st, ss, mid, index,``                    ``value, ``2` `* node + ``1``);``      ``else``        ``updateValue(arr, st, mid + ``1``, se,``                    ``index, value, ``2` `* node + ``2``);` `      ``st[node] = Math.max(st[``2` `* node + ``1``], st[``2` `* node + ``2``]);``    ``}``    ``return``;``  ``}` `  ``// Return max of elements in range from``  ``// index l (query start) to r (query end).``  ``static` `int` `getMax(``int``[] st, ``int` `n, ``int` `l, ``int` `r)``  ``{` `    ``// Check for erroneous input values``    ``if` `(l < ``0` `|| r > n - ``1` `|| l > r)``    ``{``      ``System.out.printf(``"Invalid Input\n"``);``      ``return` `-``1``;``    ``}` `    ``return` `MaxUtil(st, ``0``, n - ``1``, l, r, ``0``);``  ``}` `  ``// A recursive function that constructs Segment``  ``// Tree for array[ss..se]. si is index of``  ``// current node in segment tree st``  ``static` `int` `constructSTUtil(``int` `arr[], ``int` `ss, ``int` `se,``                             ``int``[] st, ``int` `si)``  ``{` `    ``// If there is one element in array, store``    ``// it in current node of segment tree and return``    ``if` `(ss == se) {``      ``if` `(fibonacci.contains(arr[ss]))``        ``st[si] = arr[ss];``      ``else``        ``st[si] = -``1``;``      ``return` `st[si];``    ``}` `    ``// If there are more than one elements, then``    ``// recur for left and right subtrees and``    ``// store the max of values in this node``    ``int` `mid = getMid(ss, se);` `    ``st[si] = Math.max(constructSTUtil(arr, ss, mid, st, si * ``2` `+ ``1``),``                      ``constructSTUtil(arr, mid + ``1``, se, st, si * ``2` `+ ``2``));` `    ``return` `st[si];``  ``}` `  ``/*``     ``* Function to construct segment tree``     ``* from given array. This function allocates``     ``* memory for segment tree.``     ``*/``  ``static` `int``[] constructST(``int` `arr[], ``int` `n)``  ``{` `    ``// Height of segment tree``    ``int` `x = (``int``) (Math.ceil(Math.log(n) / Math.log(``2``)));` `    ``// Maximum size of segment tree``    ``int` `max_size = ``2` `* (``int``) Math.pow(``2``, x) - ``1``;` `    ``// Allocate memory``    ``int``[] st = ``new` `int``[max_size];` `    ``// Fill the allocated memory st``    ``constructSTUtil(arr, ``0``, n - ``1``, st, ``0``);` `    ``// Return the constructed segment tree``    ``return` `st;``  ``}` `  ``// Driver code``  ``public` `static` `void` `main(String[] args)``  ``{` `    ``int` `arr[] = { ``1``, ``3``, ``5``, ``7``, ``9``, ``11` `};``    ``int` `n = arr.length;` `    ``// find the largest node value``    ``// in the array``    ``int` `maxEle = Arrays.stream(arr).max().getAsInt();` `    ``// creating a set containing``    ``// all fibonacci numbers``    ``// upto the maximum data value``    ``// in the array``    ``createHash(maxEle);` `    ``// Build segment tree from given array``    ``int``[] st = constructST(arr, n);` `    ``// Print max of values in array``    ``// from index 1 to 3``    ``System.out.println(``"Maximum fibonacci number in given range = "` `+``                       ``getMax(st, n, ``1``, ``3``));` `    ``// Update: set arr[1] = 8 and update``    ``// corresponding segment tree nodes.``    ``updateValue(arr, st, ``0``, n - ``1``, ``3``, ``8``, ``0``);` `    ``// Find max after the value is updated``    ``System.out.println(``"Updated Maximum fibonacci number in given range = "` `+``                       ``getMax(st, n, ``1``, ``3``));``  ``}``}` `// This code is contributed by sanjeev2552`

## Python3

 `# Python code for range maximum query and updates``import` `math``fibonacci ``=` `set``()` `# A utility function to get the``# middle index of given range.``def` `get_mid(s, e):``    ``return` `s ``+` `(e ``-` `s) ``/``/` `2` `# Function to create hash table``# to check Fibonacci numbers``def` `create_hash(max_element):``    ``prev ``=` `0``    ``curr ``=` `1``    ``fibonacci.add(prev)``    ``fibonacci.add(curr)` `    ``while` `curr <``=` `max_element:``        ``temp ``=` `curr ``+` `prev``        ``fibonacci.add(temp)``        ``prev ``=` `curr``        ``curr ``=` `temp` `'''  A recursive function to get the sum of``    ``values in given range of the array.``    ``The following are parameters for this``    ``function.` `    ``st       -> Pointer to segment tree``    ``node     -> Index of current node in``                ``the segment tree .``    ``ss & se  -> Starting and ending indexes``                ``of the segment represented``                ``by current node, i.e., st[node]``    ``l & r    -> Starting and ending indexes``                ``of range query '''``def` `max_util(st, ss, se, l, r, node):``    ``# If segment of this node is completely``    ``# part of given range, then return``    ``# the max of segment``    ``if` `l <``=` `ss ``and` `r >``=` `se:``        ``return` `st[node]` `    ``# If segment of this node does not``    ``# belong to given range``    ``if` `se < l ``or` `ss > r:``        ``return` `-``1` `    ``# If segment of this node is partially``    ``# the part of given range``    ``mid ``=` `get_mid(ss, se)` `    ``return` `max``(max_util(st, ss, mid, l, r,``                        ``2` `*` `node ``+` `1``),``               ``max_util(st, mid ``+` `1``, se, l,``                        ``r, ``2` `*` `node ``+` `2``))`  `''' A recursive function to update the nodes which``   ``have the given index in their range. The following``   ``are parameters st, ss and se are same as defined``   ``above index -> index of the element to be updated.'''``def` `update_value(arr, st, ss, se, index, value, node):``    ``if` `index < ss ``or` `index > se:``        ``print``(``"Invalid Input"``)``        ``return` `    ``if` `ss ``=``=` `se:``        ``# update value in array and in segment tree``        ``arr[index] ``=` `value` `        ``if` `value ``in` `fibonacci:``            ``st[node] ``=` `value``        ``else``:``            ``st[node] ``=` `-``1``    ``else``:``        ``mid ``=` `get_mid(ss, se)` `        ``if` `index >``=` `ss ``and` `index <``=` `mid:``            ``update_value(arr, st, ss, mid, index,``                         ``value, ``2` `*` `node ``+` `1``)``        ``else``:``            ``update_value(arr, st, mid ``+` `1``, se,``                         ``index, value, ``2` `*` `node ``+` `2``)` `        ``st[node] ``=` `max``(st[``2` `*` `node ``+` `1``], st[``2` `*` `node ``+` `2``])``    ``return` `# Return max of elements in range from``# index l (query start) to r (query end).``def` `get_max(st, n, l, r):``    ``# Check for erroneous input values``    ``if` `l < ``0` `or` `r > n ``-` `1` `or` `l > r:``        ``print``(``"Invalid Input"``)``        ``return` `-``1` `    ``return` `max_util(st, ``0``, n ``-` `1``, l, r, ``0``)` `# A recursive function that constructs Segment``# Tree for array[ss..se]. si is index of``# current node in segment tree st``def` `construct_st_util(arr, ss, se, st, si):``    ``# If there is one element in array, store``    ``# it in current node of segment tree and return``    ``if` `ss ``=``=` `se:``        ``if` `arr[ss] ``in` `fibonacci:``            ``st[si] ``=` `arr[ss]``        ``else``:``            ``st[si] ``=` `-``1``        ``return` `st[si]` `    ``# If there are more than one elements, then``    ``# recur for left and right subtrees and``    ``# store the max of values in this node``    ``mid ``=` `get_mid(ss, se)` `    ``st[si] ``=` `max``(construct_st_util(``        ``arr, ss, mid, st, si ``*` `2` `+` `1``),``        ``construct_st_util(arr, mid ``+` `1``, se,``                          ``st, si ``*` `2` `+` `2``))` `    ``return` `st[si]` `''' Function to construct segment tree``   ``from given array.``   ``This function allocates memory``   ``for segment tree.'''``def` `construct_st(arr, n):``    ``# Height of segment tree``    ``x ``=` `int``(math.ceil(math.log2(n)))` `    ``# Maximum size of segment tree``    ``max_size ``=` `2` `*` `(``2` `*``*` `x) ``-` `1` `    ``# Allocate memory``    ``st ``=` `[``0``] ``*` `max_size` `    ``# Fill the allocated memory st``    ``construct_st_util(arr, ``0``, n ``-` `1``, st, ``0``)` `    ``# Return the constructed segment tree``    ``return` `st` `# Driver code``if` `__name__ ``=``=` `"__main__"``:``    ``arr ``=` `[``1``, ``3``, ``5``, ``7``, ``9``, ``11``]``    ``n ``=` `len``(arr)` `    ``# find the largest node value``    ``# in the array``    ``max_ele ``=` `max``(arr)` `    ``# creating a set containing``    ``# all fibonacci numbers``    ``# upto the maximum data value``    ``# in the array``    ``create_hash(max_ele)` `    ``# Build segment tree from given array``    ``st ``=` `construct_st(arr, n)` `    ``# Print max of values in array``    ``# from index 1 to 3``    ``print``(``"Maximum fibonacci number in given range = "``,``          ``get_max(st, n, ``1``, ``3``))` `    ``# Update: set arr[1] = 8 and update``    ``# corresponding segment tree nodes.``    ``update_value(arr, st, ``0``, n ``-` `1``, ``3``, ``8``, ``0``)` `    ``# Find max after the value is updated``    ``print``(``"Updated Maximum Fibonacci number in given range = "``,``          ``get_max(st, n, ``1``, ``3``))``    ` `# This code is contributed by akashish__`

## C#

 `// Include namespace system``using` `System;``using` `System.Collections.Generic;``using` `System.Linq;``using` `System.Collections;` `public` `class` `GFG``{``  ``public` `static` `HashSet<``int``> fibonacci = ``new` `HashSet<``int``>();` `  ``// A utility function to get the``  ``// middle index of given range.``  ``public` `static` `int` `getMid(``int` `s, ``int` `e)``  ``{``    ``return` `s + (``int``)((e - s) / 2);``  ``}` `  ``// Function to create hash table``  ``// to check Fibonacci numbers``  ``public` `static` `void` `createHash(``int` `maxElement)``  ``{``    ``var` `prev = 0;``    ``var` `curr = 1;``    ``fibonacci.Add(prev);``    ``fibonacci.Add(curr);``    ``while` `(curr <= maxElement)``    ``{``      ``var` `temp = curr + prev;``      ``fibonacci.Add(temp);``      ``prev = curr;``      ``curr = temp;``    ``}``  ``}``  ``//     * A recursive function to get the sum of``  ``//     * values in given range of the array.``  ``//     * The following are parameters for this function.``  ``//     *``  ``//     * st       -> Pointer to segment tree``  ``//     * node     -> Index of current node``  ``//     *             in the segment tree .``  ``//     * ss & se  -> Starting and ending indexes``  ``//     *             of the segment represented``  ``//     *             by current node, i.e., st[node]``  ``//     * l & r    -> Starting and ending indexes``  ``//     *             of range query``  ``public` `static` `int` `MaxUtil(``int``[] st, ``int` `ss, ``int` `se, ``int` `l, ``int` `r, ``int` `node)``  ``{``    ``// If segment of this node is completely``    ``// part of given range, then return``    ``// the max of segment``    ``if` `(l <= ss && r >= se)``    ``{``      ``return` `st[node];``    ``}``    ``// If segment of this node does not``    ``// belong to given range``    ``if` `(se < l || ss > r)``    ``{``      ``return` `-1;``    ``}` `    ``// If segment of this node is partially``    ``// the part of given range``    ``var` `mid = GFG.getMid(ss, se);``    ``return` `Math.Max(GFG.MaxUtil(st, ss, mid, l, r, 2 * node + 1),GFG.MaxUtil(st, mid + 1, se, l, r, 2 * node + 2));``  ``}` `  ``//     * A recursive function to update the nodes which``  ``//     * have the given index in their range. The following``  ``//     * are parameters st, ss and se are same as defined``  ``//     * above index -> index of the element to be updated.``  ``public` `static` `void` `updateValue(``int``[] arr, ``int``[] st, ``int` `ss, ``int` `se, ``int` `index, ``int` `value, ``int` `node)``  ``{``    ``if` `(index < ss || index > se)``    ``{``      ``Console.WriteLine(``"Invalid Input"``);``      ``return``;``    ``}``    ``if` `(ss == se)``    ``{` `      ``// update value in array and in segment tree``      ``arr[index] = value;``      ``if` `(fibonacci.Contains(value))``      ``{``        ``st[node] = value;``      ``}``      ``else``      ``{``        ``st[node] = -1;``      ``}``    ``}``    ``else``    ``{``      ``var` `mid = GFG.getMid(ss, se);``      ``if` `(index >= ss && index <= mid)``      ``{``        ``GFG.updateValue(arr, st, ss, mid, index, value, 2 * node + 1);``      ``}``      ``else``      ``{``        ``GFG.updateValue(arr, st, mid + 1, se, index, value, 2 * node + 2);``      ``}``      ``st[node] = Math.Max(st[2 * node + 1],st[2 * node + 2]);``    ``}``    ``return``;``  ``}` `  ``// Return max of elements in range from``  ``// index l (query start) to r (query end).``  ``public` `static` `int` `getMax(``int``[] st, ``int` `n, ``int` `l, ``int` `r)``  ``{` `    ``// Check for erroneous input values``    ``if` `(l < 0 || r > n - 1 || l > r)``    ``{``      ``Console.Write(``"Invalid Input\n"``);``      ``return` `-1;``    ``}``    ``return` `GFG.MaxUtil(st, 0, n - 1, l, r, 0);``  ``}` `  ``// A recursive function that constructs Segment``  ``// Tree for array[ss..se]. si is index of``  ``// current node in segment tree st``  ``public` `static` `int` `constructSTUtil(``int``[] arr, ``int` `ss, ``int` `se, ``int``[] st, ``int` `si)``  ``{` `    ``// If there is one element in array, store``    ``// it in current node of segment tree and return``    ``if` `(ss == se)``    ``{``      ``if` `(fibonacci.Contains(arr[ss]))``      ``{``        ``st[si] = arr[ss];``      ``}``      ``else``      ``{``        ``st[si] = -1;``      ``}``      ``return` `st[si];``    ``}` `    ``// If there are more than one elements, then``    ``// recur for left and right subtrees and``    ``// store the max of values in this node``    ``var` `mid = GFG.getMid(ss, se);``    ``st[si] = Math.Max(GFG.constructSTUtil(arr, ss, mid, st, si * 2 + 1),GFG.constructSTUtil(arr, mid + 1, se, st, si * 2 + 2));``    ``return` `st[si];``  ``}` `  ``//     * Function to construct segment tree``  ``//     * from given array. This function allocates``  ``//     * memory for segment tree.``  ``public` `static` `int``[] constructST(``int``[] arr, ``int` `n)``  ``{` `    ``// Height of segment tree``    ``var` `x = (``int``)(Math.Ceiling(Math.Log(n) / Math.Log(2)));` `    ``// Maximum size of segment tree``    ``var` `max_size = 2 * (``int``)Math.Pow(2,x) - 1;` `    ``// Allocate memory``    ``int``[] st = ``new` `int``[max_size];` `    ``// Fill the allocated memory st``    ``GFG.constructSTUtil(arr, 0, n - 1, st, 0);` `    ``// Return the constructed segment tree``    ``return` `st;``  ``}` `  ``// Driver code``  ``public` `static` `void` `Main(String[] args)``  ``{``    ``int``[] arr = {1, 3, 5, 7, 9, 11};``    ``var` `n = arr.Length;` `    ``// find the largest node value``    ``// in the array``    ``var` `maxEle = arr.Max();` `    ``// creating a set containing``    ``// all fibonacci numbers``    ``// upto the maximum data value``    ``// in the array``    ``GFG.createHash(maxEle);` `    ``// Build segment tree from given array``    ``int``[] st = GFG.constructST(arr, n);` `    ``// Print max of values in array``    ``// from index 1 to 3``    ``Console.WriteLine(``"Maximum fibonacci number in given range = "` `+ GFG.getMax(st, n, 1, 3).ToString());` `    ``// Update: set arr[1] = 8 and update``    ``// corresponding segment tree nodes.``    ``GFG.updateValue(arr, st, 0, n - 1, 3, 8, 0);` `    ``// Find max after the value is updated``    ``Console.WriteLine(``"Updated Maximum fibonacci number in given range = "` `+ GFG.getMax(st, n, 1, 3).ToString());``  ``}``}` `// This code is contributed by aadityaburujwale.`

## Javascript

 `// JavaScript code for range maximum query and updates` `let fibonacci = ``new` `Set();` `// A utility function to get the``// middle index of given range.``function` `getMid(s, e)``{``    ``return` `s + Math.floor((e - s) / 2);``}` `// Function to create hash table``// to check Fibonacci numbers``function` `createHash(maxElement)``{``    ``let prev = 0;``    ``let curr = 1;``    ``fibonacci.add(prev);``    ``fibonacci.add(curr);` `    ``while` `(curr <= maxElement) {``        ``let temp = curr + prev;``        ``fibonacci.add(temp);``        ``prev = curr;``        ``curr = temp;``    ``}``}` `/*  A recursive function to get the sum of``    ``values in given range of the array.``    ``The following are parameters for this``    ``function.` `    ``st       -> Pointer to segment tree``    ``node     -> Index of current node in``                ``the segment tree .``    ``ss & se  -> Starting and ending indexes``                ``of the segment represented``                ``by current node, i.e., st[node]``    ``l & r    -> Starting and ending indexes``                ``of range query */``function` `MaxUtil(st, ss, se, l, r, node)``{``    ``// If segment of this node is completely``    ``// part of given range, then return``    ``// the max of segment``    ``if` `(l <= ss && r >= se)``        ``return` `st[node];` `    ``// If segment of this node does not``    ``// belong to given range``    ``if` `(se < l || ss > r)``        ``return` `-1;` `    ``// If segment of this node is partially``    ``// the part of given range``    ``let mid = getMid(ss, se);` `    ``return` `Math.max(MaxUtil(st, ss, mid, l, r, 2 * node + 1),MaxUtil(st, mid + 1, se, l, r, 2 * node + 2));``}` `/* A recursive function to update the nodes which``   ``have the given index in their range. The following``   ``are parameters st, ss and se are same as defined``   ``above index -> index of the element to be updated.*/``function` `updateValue(arr, st, ss, se, index, value, node)``{``    ``if` `(index < ss || index > se) {``        ``console.log(``"Invalid Input"``);``        ``return``;``    ``}` `    ``if` `(ss == se) {``        ``// update value in array and in segment tree``        ``arr[index] = value;` `        ``if` `(fibonacci.has(value))``            ``st[node] = value;``        ``else``            ``st[node] = -1;``    ``}``    ``else` `{``        ``let mid = getMid(ss, se);` `        ``if` `(index >= ss && index <= mid)``            ``updateValue(arr, st, ss, mid, index, value, 2 * node + 1);``        ``else``            ``updateValue(arr, st, mid + 1, se, index, value, 2 * node + 2);` `        ``st[node] = Math.max(st[2 * node + 1], st[2 * node + 2]);``    ``}``    ``return``;``}` `// Return max of elements in range from``// index l (query start) to r (query end).``function` `getMax(st, n, l, r)``{``    ``// Check for erroneous input values``    ``if` `(l < 0 || r > n - 1 || l > r) {``        ``console.log(``"Invalid Input"``);``        ``return` `-1;``    ``}` `    ``return` `MaxUtil(st, 0, n - 1, l, r, 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, st, si)``{``    ``// If there is one element in array, store``    ``// it in current node of segment tree and return``    ``if` `(ss == se) {``        ``if` `(fibonacci.has(arr[ss]))``            ``st[si] = arr[ss];``        ``else``            ``st[si] = -1;``        ``return` `st[si];``    ``}` `    ``// If there are more than one elements, then``    ``// recur for left and right subtrees and``    ``// store the max of values in this node``    ``let mid = getMid(ss, se);` `    ``st[si] = Math.max(constructSTUtil(arr, ss, mid, st, si * 2 + 1),constructSTUtil(``arr, mid + 1, se, st, si * 2 + 2));` `    ``return` `st[si];``}` `/* Function to construct segment tree``   ``from given array.``   ``This function allocates memory``   ``for segment tree.*/``function` `constructST(arr, n)``{``    ``// Height of segment tree``    ``let x = Math.floor(Math.ceil(Math.log2(n)));` `    ``// Maximum size of segment tree``    ``let max_size = 2 * Math.floor(Math.pow(2, x)) - 1;` `    ``// Allocate memory``    ``let st = ``new` `Array(max_size).fill(0);` `    ``// Fill the allocated memory st``    ``constructSTUtil(arr, 0, n - 1, st, 0);` `    ``// Return the constructed segment tree``    ``return` `st;``}` `// Driver code``let arr = [ 1, 3, 5, 7, 9, 11 ];``let n = arr.length;` `// find the largest node value``// in the array` `let maxEle = Math.max(...arr);` `// creating a set containing``// all fibonacci numbers``// upto the maximum data value``// in the array``createHash(maxEle);` `// Build segment tree from given array``let st = constructST(arr, n);` `// Print max of values in array``// from index 1 to 3``console.log(``"Maximum fibonacci number in given range = "``,getMax(st, n, 1, 3));` `// Update: set arr[1] = 8 and update``// corresponding segment tree nodes.``updateValue(arr, st, 0, n - 1, 3, 8, 0);` `// Find max after the value is updated``console.log(``"Updated Maximum Fibonacci number in given range = "``, getMax(st, n, 1, 3));` `// The code is contributed by Gautam goel (gautamgoelo962)`

Output:
Maximum fibonacci number in given range = 5
Updated Maximum fibonacci number in given range = 8

My Personal Notes arrow_drop_up