# Array range queries to count the number of Fibonacci numbers with updates

• Last Updated : 20 Jun, 2022

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

• query(start, end): Print the number of fibonacci numbers in the subarray from start to end
• update(i, x): Add x to the array element referenced by array index i, that is: arr[i] = x

Examples:

Input: arr = { 1, 2, 3, 4, 8, 9 }
Query 1: query(start = 0, end = 4)
Query 2: update(i = 3, x = 5)
Query 3: query(start = 0, end = 4)
Output:

Explanation
In Query 1, the subarray [0…4] has 4 fibonacci numbers viz. {1, 2, 3, 8}
In Query 2, the value at index 3 is updated to 5, the array arr now is, {1, 2, 3, 5, 8, 9}
In Query 3, the subarray [0…4] has 5 fibonacci numbers viz. {1, 2, 3, 5, 8}

Approach: To handle both point updates and range queries, a segment tree is optimal for this purpose.
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 arri. We can take MAX which will be used to test a number in O(1) time complexity.
Building the segment tree:

• The problem is now reduced to the subarray sum using segment tree problem.
• Now, we can build the segment tree where a leaf node is represented as either 0 (if it is not a prime number) or 1 (if it is a Fibonacci number).
• The internal nodes of the segment tree equal to the sum of its child nodes, thus a node represent the total Fibonacci numbers in the range from L to R with range [L, R] falling under this node and the sub-tree underneath it.

• Whenever we receive a query from beginning to end, we can query the segment tree for the sum of nodes in range from start to end, which in turn represent the number of Fibonacci numbers in the range start to end.

• To perform a point update and to update the value at index i to x, we check for the following cases:
Let the old value of arri be y and the new value be x.
1. Case 1: Fibonacci: If x and y both are Fibonacci numbers
Count of Fibonacci numbers in the subarray does not change so we just update array and do not modify the segment tree
2. Case 2: If x and y both are not Fibonacci numbers
Count of Fibonacci numbers in the subarray does not change so we just update array and do not modify the segment tree
3. Case 3: If y is a Fibonacci number but x is not
Count of Fibonacci numbers in the subarray decreases so we update array and add -1 to every range. The index i which is to be updated is a part of in the segment tree
4. Case 4: If y is not a Fibonacci number but x is a Fibonacci number
Count of Fibonacci numbers in the subarray increases so we update array and add 1 to every range. The index i which is to be updated is a part of in the segment tree

Below is the implementation of the above approach:

## C++

 `// C++ program to find number of fibonacci numbers``// in a subarray and performing updates` `#include ``using` `namespace` `std;` `#define MAX 1000` `// Function to create hash table``// to check Fibonacci numbers``void` `createHash(set<``int``>& hash,``                ``int` `maxElement)``{``    ``int` `prev = 0, curr = 1;``    ``hash.insert(prev);``    ``hash.insert(curr);` `    ``while` `(curr <= maxElement) {``        ``int` `temp = curr + prev;``        ``hash.insert(temp);``        ``prev = curr;``        ``curr = temp;``    ``}``}` `// A utility function to get the middle``// index from corner indexes.``int` `getMid(``int` `s, ``int` `e)``{``    ``return` `s + (e - s) / 2;``}` `// Recursive function to get the number``// of Fibonacci numbers in a given range``/* where``    ``st    --> Pointer to segment tree``    ``index --> Index of current node in the``              ``segment tree. Initially 0 is passed``              ``as root is always at index 0``    ``ss & se  --> Starting and ending indexes of``              ``the segment represented by current``              ``node, i.e., st[index]``    ``qs & qe  --> Starting and ending indexes``              ``of query range  ``    ``*/``int` `queryFibonacciUtil(``int``* st, ``int` `ss,``                       ``int` `se, ``int` `qs,``                       ``int` `qe, ``int` `index)``{``    ``// If segment of this node is a part``    ``// of given range, then return``    ``// the number of Fibonacci numbers``    ``// in the segment``    ``if` `(qs <= ss && qe >= se)``        ``return` `st[index];` `    ``// If segment of this node``    ``// is outside the given range``    ``if` `(se < qs || ss > qe)``        ``return` `0;` `    ``// If a part of this segment``    ``// overlaps with the given range``    ``int` `mid = getMid(ss, se);``    ``return` `queryFibonacciUtil(st, ss, mid, qs,``                              ``qe, 2 * index + 1)``           ``+ queryFibonacciUtil(st, mid + 1, se,``                                ``qs, qe, 2 * index + 2);``}` `// Recursive function to update``// the nodes which have the given``// index in their range.``/* where``    ``st, si, ss and se are same as getSumUtil()``    ``i --> index of the element to be updated.``          ``This index is in input array.``   ``diff --> Value to be added to all nodes``          ``which have i in range``*/``void` `updateValueUtil(``int``* st, ``int` `ss,``                     ``int` `se, ``int` `i,``                     ``int` `diff, ``int` `si)``{``    ``// Base Case:``    ``// If the input index lies outside``    ``// the range of this segment``    ``if` `(i < ss || i > se)``        ``return``;` `    ``// If the input index is in range``    ``// of this node, then update the value``    ``// of the node and its children``    ``st[si] = st[si] + diff;``    ``if` `(se != ss) {` `        ``int` `mid = getMid(ss, se);``        ``updateValueUtil(st, ss, mid, i,``                        ``diff, 2 * si + 1);``        ``updateValueUtil(st, mid + 1, se,``                        ``i, diff, 2 * si + 2);``    ``}``}` `// Function to update a value in the``// input array and segment tree.``// It uses updateValueUtil() to update``// the value in segment tree``void` `updateValue(``int` `arr[], ``int``* st,``                 ``int` `n, ``int` `i,``                 ``int` `new_val,``                 ``set<``int``> hash)``{``    ``// Check for erroneous input index``    ``if` `(i < 0 || i > n - 1) {``        ``printf``(``"Invalid Input"``);``        ``return``;``    ``}` `    ``int` `diff, oldValue;` `    ``oldValue = arr[i];` `    ``// Update the value in array``    ``arr[i] = new_val;` `    ``// Case 1: Old and new values``    ``// both are Fibonacci numbers``    ``if` `(hash.find(oldValue) != hash.end()``        ``&& hash.find(new_val) != hash.end())``        ``return``;` `    ``// Case 2: Old and new values``    ``// both not Fibonacci numbers``    ``if` `(hash.find(oldValue) == hash.end()``        ``&& hash.find(new_val) == hash.end())``        ``return``;` `    ``// Case 3: Old value was Fibonacci,``    ``// new value is non Fibonacci``    ``if` `(hash.find(oldValue) != hash.end()``        ``&& hash.find(new_val) == hash.end()) {``        ``diff = -1;``    ``}` `    ``// Case 4: Old value was non Fibonacci,``    ``// new_val is Fibonacci``    ``if` `(hash.find(oldValue) == hash.end()``        ``&& hash.find(new_val) != hash.end()) {``        ``diff = 1;``    ``}` `    ``// Update the values of nodes in segment tree``    ``updateValueUtil(st, 0, n - 1, i, diff, 0);``}` `// Return number of Fibonacci numbers``// in range from index qs (query start)``// to qe (query end).``// It mainly uses queryFibonacciUtil()``void` `queryFibonacci(``int``* st, ``int` `n,``                    ``int` `qs, ``int` `qe)``{``    ``int` `FibonacciInRange``        ``= queryFibonacciUtil(st, 0, n - 1,``                             ``qs, qe, 0);` `    ``cout << ``"Number of Fibonacci numbers "``         ``<< ``"in subarray from "``         ``<< qs << ``" to "``         ``<< qe << ``" = "``         ``<< FibonacciInRange << ``"\n"``;``}` `// 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, set<``int``> hash)``{``    ``// If there is one element in array,``    ``// check if it is Fibonacci number``    ``// then store 1 in the segment tree``    ``// else store 0 and return``    ``if` `(ss == se) {` `        ``// if arr[ss] is fibonacci number``        ``if` `(hash.find(arr[ss]) != hash.end())``            ``st[si] = 1;``        ``else``            ``st[si] = 0;` `        ``return` `st[si];``    ``}` `    ``// If there are more than one elements,``    ``// then recur for left and right subtrees``    ``// and store the sum of the``    ``// two values in this node``    ``int` `mid = getMid(ss, se);``    ``st[si] = constructSTUtil(arr, ss, mid, st,``                             ``si * 2 + 1, hash)``             ``+ constructSTUtil(arr, mid + 1, se, st,``                               ``si * 2 + 2, hash);``    ``return` `st[si];``}` `// Function to construct a segment tree from given array.``// This function allocates memory for segment tree and``// calls constructSTUtil() to fill the allocated memory``int``* constructST(``int` `arr[], ``int` `n, set<``int``> hash)``{``    ``// Allocate memory for segment tree` `    ``// Height of segment tree``    ``int` `x = (``int``)(``ceil``(log2(n)));` `    ``// Maximum size of segment tree``    ``int` `max_size = 2 * (``int``)``pow``(2, x) - 1;` `    ``int``* st = ``new` `int``[max_size];` `    ``// Fill the allocated memory st``    ``constructSTUtil(arr, 0, n - 1, st, 0, hash);` `    ``// Return the constructed segment tree``    ``return` `st;``}` `// Driver Code``int` `main()``{` `    ``int` `arr[] = { 1, 2, 3, 4, 8, 9 };``    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr);` `    ``// 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``    ``set<``int``> hash;``    ``createHash(hash, maxEle);` `    ``// Build segment tree from given array``    ``int``* st = constructST(arr, n, hash);` `    ``// Query 1: Query(start = 0, end = 4)``    ``int` `start = 0;``    ``int` `end = 4;``    ``queryFibonacci(st, n, start, end);` `    ``// Query 2: Update(i = 3, x = 5),``    ``// i.e Update a[i] to x``    ``int` `i = 3;``    ``int` `x = 5;``    ``updateValue(arr, st, n, i, x, hash);` `    ``// uncomment to see array after update``    ``// for(int i = 0; i < n; i++)``    ``// cout << arr[i] << " ";` `    ``// Query 3: Query(start = 0, end = 4)``    ``start = 0;``    ``end = 4;``    ``queryFibonacci(st, n, start, end);` `    ``return` `0;``}`

## Java

 `// Java program to find number of fibonacci numbers``// in a subarray and performing updates``import` `java.util.Arrays;``import` `java.util.HashSet;``import` `java.util.Set;``class` `GFG``{``  ``static` `final` `int` `MAX = ``1000``;` `  ``// Function to create hash table``  ``// to check Fibonacci numbers``  ``static` `void` `createHash(Set hash, ``int` `maxElement)``  ``{``    ``int` `prev = ``0``, curr = ``1``;``    ``hash.add(prev);``    ``hash.add(curr);``    ``while` `(curr <= maxElement)``    ``{``      ``int` `temp = curr + prev;``      ``hash.add(temp);``      ``prev = curr;``      ``curr = temp;``    ``}``  ``}` `  ``// A utility function to get the middle``  ``// index from corner indexes.``  ``static` `int` `getMid(``int` `s, ``int` `e)``  ``{``    ``return` `s + (e - s) / ``2``;``  ``}` `  ``// Recursive function to get the number``  ``// of Fibonacci numbers in a given range``  ``/*``     ``* where st --> Pointer to segment tree index --> Index of current node in the``     ``* segment tree. Initially 0 is passed as root is always at index 0 ss & se -->``     ``* Starting and ending indexes of the segment represented by current node, i.e.,``     ``* st[index] qs & qe --> Starting and ending indexes of query range``     ``*/``  ``static` `int` `queryFibonacciUtil(``int``[] st, ``int` `ss, ``int` `se,``                                ``int` `qs, ``int` `qe, ``int` `index)``  ``{` `    ``// If segment of this node is a part``    ``// of given range, then return``    ``// the number of Fibonacci numbers``    ``// in the segment``    ``if` `(qs <= ss && qe >= se)``      ``return` `st[index];` `    ``// If segment of this node``    ``// is outside the given range``    ``if` `(se < qs || ss > qe)``      ``return` `0``;` `    ``// If a part of this segment``    ``// overlaps with the given range``    ``int` `mid = getMid(ss, se);``    ``return` `queryFibonacciUtil(st, ss, mid,``                              ``qs, qe, ``2` `* index + ``1``)``      ``+ queryFibonacciUtil(st, mid + ``1``, se,``                           ``qs, qe, ``2` `* index + ``2``);``  ``}` `  ``// Recursive function to update``  ``// the nodes which have the given``  ``// index in their range.``  ``/*``     ``* where st, si, ss and se are same as getSumUtil() i --> index of the element``     ``* to be updated. This index is in input array. diff --> Value to be added to``     ``* all nodes which have i in range``     ``*/``  ``static` `void` `updateValueUtil(``int``[] st, ``int` `ss,``                              ``int` `se, ``int` `i,``                              ``int` `diff, ``int` `si)``  ``{` `    ``// Base Case:``    ``// If the input index lies outside``    ``// the range of this segment``    ``if` `(i < ss || i > se)``      ``return``;` `    ``// If the input index is in range``    ``// of this node, then update the value``    ``// of the node and its children``    ``st[si] = st[si] + diff;``    ``if` `(se != ss)``    ``{` `      ``int` `mid = getMid(ss, se);``      ``updateValueUtil(st, ss, mid, i,``                      ``diff, ``2` `* si + ``1``);``      ``updateValueUtil(st, mid + ``1``, se, i,``                      ``diff, ``2` `* si + ``2``);``    ``}``  ``}` `  ``// Function to update a value in the``  ``// input array and segment tree.``  ``// It uses updateValueUtil() to update``  ``// the value in segment tree``  ``static` `void` `updateValue(``int` `arr[], ``int``[] st, ``int` `n,``                          ``int` `i, ``int` `new_val, Set hash)``  ``{` `    ``// Check for erroneous input index``    ``if` `(i < ``0` `|| i > n - ``1``)``    ``{``      ``System.out.printf(``"Invalid Input"``);``      ``return``;``    ``}` `    ``int` `diff = ``0``, oldValue;``    ``oldValue = arr[i];` `    ``// Update the value in array``    ``arr[i] = new_val;` `    ``// Case 1: Old and new values``    ``// both are Fibonacci numbers``    ``if` `(hash.contains(oldValue) &&``        ``hash.contains(new_val))``      ``return``;` `    ``// Case 2: Old and new values``    ``// both not Fibonacci numbers``    ``if` `(!hash.contains(oldValue) &&``        ``!hash.contains(new_val))``      ``return``;` `    ``// Case 3: Old value was Fibonacci,``    ``// new value is non Fibonacci``    ``if` `(hash.contains(oldValue) &&``        ``!hash.contains(new_val))``    ``{``      ``diff = -``1``;``    ``}` `    ``// Case 4: Old value was non Fibonacci,``    ``// new_val is Fibonacci``    ``if` `(!hash.contains(oldValue) &&``        ``hash.contains(new_val))``    ``{``      ``diff = ``1``;``    ``}` `    ``// Update the values of nodes in segment tree``    ``updateValueUtil(st, ``0``, n - ``1``, i, diff, ``0``);``  ``}` `  ``// Return number of Fibonacci numbers``  ``// in range from index qs (query start)``  ``// to qe (query end).``  ``// It mainly uses queryFibonacciUtil()``  ``static` `void` `queryFibonacci(``int``[] st, ``int` `n, ``int` `qs, ``int` `qe)``  ``{``    ``int` `FibonacciInRange = queryFibonacciUtil(st, ``0``,``                                              ``n - ``1``, qs, qe, ``0``);``    ``System.out.printf(``"Number of Fibonacci numbers in subarray from %d to %d = %d\n"``, qs, qe, FibonacciInRange);``  ``}` `  ``// 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, Set hash)``  ``{` `    ``// If there is one element in array,``    ``// check if it is Fibonacci number``    ``// then store 1 in the segment tree``    ``// else store 0 and return``    ``if` `(ss == se)``    ``{` `      ``// if arr[ss] is fibonacci number``      ``if` `(hash.contains(arr[ss]))``        ``st[si] = ``1``;``      ``else``        ``st[si] = ``0``;         ``      ``return` `st[si];``    ``}` `    ``// If there are more than one elements,``    ``// then recur for left and right subtrees``    ``// and store the sum of the``    ``// two values in this node``    ``int` `mid = getMid(ss, se);``    ``st[si] = constructSTUtil(arr, ss, mid, st,``                             ``si * ``2` `+ ``1``, hash)``      ``+ constructSTUtil(arr, mid + ``1``, se,``                        ``st, si * ``2` `+ ``2``, hash);``    ``return` `st[si];``  ``}` `  ``// Function to construct a segment tree from given array.``  ``// This function allocates memory for segment tree and``  ``// calls constructSTUtil() to fill the allocated memory``  ``static` `int``[] constructST(``int` `arr[], ``int` `n, Set hash)``  ``{` `    ``// Allocate memory for segment tree` `    ``// 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``;``    ``int``[] st = ``new` `int``[max_size];` `    ``// Fill the allocated memory st``    ``constructSTUtil(arr, ``0``, n - ``1``, st, ``0``, hash);` `    ``// Return the constructed segment tree``    ``return` `st;``  ``}` `  ``// Driver Code``  ``public` `static` `void` `main(String[] args)``  ``{` `    ``int` `arr[] = { ``1``, ``2``, ``3``, ``4``, ``8``, ``9` `};``    ``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``    ``Set hash = ``new` `HashSet<>();``    ``createHash(hash, maxEle);` `    ``// Build segment tree from given array``    ``int``[] st = constructST(arr, n, hash);` `    ``// Query 1: Query(start = 0, end = 4)``    ``int` `start = ``0``;``    ``int` `end = ``4``;``    ``queryFibonacci(st, n, start, end);` `    ``// Query 2: Update(i = 3, x = 5),``    ``// i.e Update a[i] to x``    ``int` `i = ``3``;``    ``int` `x = ``5``;``    ``updateValue(arr, st, n, i, x, hash);` `    ``// uncomment to see array after update``    ``// for(int i = 0; i < n; i++)``    ``// cout << arr[i] << " ";` `    ``// Query 3: Query(start = 0, end = 4)``    ``start = ``0``;``    ``end = ``4``;``    ``queryFibonacci(st, n, start, end);``  ``}``}` `// This code is contributed by sanjeev2552`

## Python3

 `# Python program to find number of fibonacci numbers``# in a subarray and performing updates``import` `math``MAX` `=` `1000` `# Function to create hash table``# to check Fibonacci numbers``def` `createHash(``hash``, maxElement):``    ``prev ``=` `0``    ``curr ``=` `1``    ``hash``.add(prev)``    ``hash``.add(curr)` `    ``while` `(curr <``=` `maxElement):``        ``temp ``=` `curr ``+` `prev``        ``hash``.add(temp)``        ``prev ``=` `curr``        ``curr ``=` `temp` `# A utility function to get the middle``# index from corner indexes.`  `def` `getMid(s, e):``    ``return` `math.floor(s ``+` `(e ``-` `s) ``/` `2``)` `# Recursive function to get the number``# of Fibonacci numbers in a given range``   ``# where``   ``#  st    --> Pointer to segment tree``   ``#  index --> Index of current node in the``   ``#            segment tree. Initially 0 is passed``   ``#            as root is always at index 0``   ``#  ss & se  --> Starting and ending indexes of``   ``#            the segment represented by current``   ``#            node, i.e., st[index]``   ``#  qs & qe  --> Starting and ending indexes``   ``#            of query range``def` `queryFibonacciUtil(st, ss, se, qs, qe, index):``  ` `    ``# If segment of this node is a part``    ``# of given range, then return``    ``# the number of Fibonacci numbers``    ``# in the segment``    ``if` `(qs <``=` `ss ``and` `qe >``=` `se):``        ``return` `st[index]` `    ``# If segment of this node``    ``# is outside the given range``    ``if` `(se < qs ``or` `ss > qe):``        ``return` `0` `    ``# If a part of this segment``    ``# overlaps with the given range``    ``mid ``=` `getMid(ss, se)``    ``return` `queryFibonacciUtil(st, ss, mid, qs, qe, ``2` `*` `index ``+` `1``) ``+` `queryFibonacciUtil(st, mid ``+` `1``, se, qs, qe, ``2` `*` `index ``+` `2``)` `# Recursive function to update``# the nodes which have the given``# index in their range.``   ``# where``   ``#  st, si, ss and se are same as getSumUtil()``   ``#  i --> index of the element to be updated.``   ``#        This index is in input array.``   ``# diff --> Value to be added to all nodes``   ``#        which have i in range``def` `updateValueUtil(st, ss, se, i, diff, si):``    ``# Base Case:``    ``# If the input index lies outside``    ``# the range of this segment``    ``if` `(i < ss ``or` `i > se):``        ``return` `    ``# If the input index is in range``    ``# of this node, then update the value``    ``# of the node and its children``    ``st[si] ``=` `st[si] ``+` `diff``    ``if` `(se !``=` `ss):``        ``mid ``=` `getMid(ss, se)``        ``updateValueUtil(st, ss, mid, i, diff, ``2` `*` `si ``+` `1``)``        ``updateValueUtil(st, mid ``+` `1``, se, i, diff, ``2` `*` `si ``+` `2``)` `# Function to update a value in the``# input array and segment tree.``# It uses updateValueUtil() to update``# the value in segment tree``def` `updateValue(arr, st, n, i, new_val, ``hash``):``    ``# Check for erroneous input index``    ``if` `(i < ``0` `or` `i > n ``-` `1``):``        ``print``(``"Invalid Input"``)``        ``return` `    ``diff ``=` `0``    ``oldValue ``=` `0` `    ``oldValue ``=` `arr[i]` `    ``# Update the value in array``    ``arr[i] ``=` `new_val` `    ``# Case 1: Old and new values``    ``# both are Fibonacci numbers``    ``if` `oldValue ``in` `hash``:``        ``if` `new_val ``in` `hash``:``            ``return` `    ``# Case 2: Old and new values``    ``# both not Fibonacci numbers``    ``if` `not` `oldValue ``in` `hash``:``        ``if` `not` `new_val ``in` `hash``:``            ``return` `    ``# Case 3: Old value was Fibonacci,``    ``# new value is non Fibonacci``    ``if` `oldValue ``in` `hash``:``        ``if` `not` `new_val ``in` `hash``:``            ``diff ``=` `-``1` `    ``# Case 4: Old value was non Fibonacci,``    ``# new_val is Fibonacci``    ``if` `not` `oldValue ``in` `hash``:``        ``if` `new_val ``in` `hash``:``            ``diff ``=` `1` `    ``# Update the values of nodes in segment tree``    ``updateValueUtil(st, ``0``, n ``-` `1``, i, diff, ``0``)` `# Return number of Fibonacci numbers``# in range from index qs (query start)``# to qe (query end).``# It mainly uses queryFibonacciUtil()``def` `queryFibonacci(st, n, qs, qe):``    ``FibonacciInRange ``=` `queryFibonacciUtil(st, ``0``, n ``-` `1``, qs, qe, ``0``)` `    ``print``(``        ``f``"Number of Fibonacci numbers in subarray from {qs} to {qe} = {FibonacciInRange}"``)` `# 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, st, si, ``hash``):``    ``# If there is one element in array,``    ``# check if it is Fibonacci number``    ``# then store 1 in the segment tree``    ``# else store 0 and return``    ``if` `(ss ``=``=` `se):` `        ``# if arr[ss] is fibonacci number``        ``if` `arr[ss] ``in` `hash``:``            ``st[si] ``=` `1``        ``else``:``            ``st[si] ``=` `0` `        ``return` `st[si]` `    ``# If there are more than one elements,``    ``# then recur for left and right subtrees``    ``# and store the sum of the``    ``# two values in this node``    ``mid ``=` `getMid(ss, se)``    ``st[si] ``=` `constructSTUtil(arr, ss, mid, st, si ``*` `2` `+` `1``, ``hash``) ``+` `\``        ``constructSTUtil(arr, mid ``+` `1``, se, st, si ``*` `2` `+` `2``, ``hash``)``    ``return` `st[si]` `# Function to construct a segment tree from given array.``# This function allocates memory for segment tree and``# calls constructSTUtil() to fill the allocated memory``def` `constructST(arr, n, ``hash``):``    ``# Allocate memory for segment tree` `    ``# Height of segment tree``    ``x ``=` `math.floor(math.ceil(math.log2(n)))` `    ``# Maximum size of segment tree``    ``max_size ``=` `2` `*` `math.floor(math.``pow``(``2``, x)) ``-` `1` `    ``st ``=` `[``0``]``*``max_size` `    ``# Fill the allocated memory st``    ``constructSTUtil(arr, ``0``, n ``-` `1``, st, ``0``, ``hash``)` `    ``# Return the constructed segment tree``    ``return` `st` `# Driver Code``arr ``=` `[``1``, ``2``, ``3``, ``4``, ``8``, ``9``]``n ``=` `len``(arr)` `# find the largest node value in the array``maxEle ``=` `-``1``for` `i ``in` `range``(``len``(arr)):``    ``if` `arr[i] > maxEle:``        ``maxEle ``=` `arr[i]`  `# Creating a set containing all Fibonacci numbers``# upto the maximum data value in the array``hash` `=` `set``()``createHash(``hash``, maxEle)` `# Build segment tree from given array``st ``=` `constructST(arr, n, ``hash``)` `# Query 1: Query(start = 0, end = 4)``start ``=` `0``end ``=` `4``queryFibonacci(st, n, start, end)` `# Query 2: Update(i = 3, x = 5),``# i.e Update a[i] to x``i ``=` `3``x ``=` `5``updateValue(arr, st, n, i, x, ``hash``)` `# uncomment to see array after update``# for(int i = 0; i < n; i++)``# cout << arr[i] << " ";` `# Query 3: Query(start = 0, end = 4)``start ``=` `0``end ``=` `4``queryFibonacci(st, n, start, end)` `# The code is contributed by Gautam goel (gautamgoel962)`

## Javascript

 ``

Output:

```Number of Fibonacci numbers in subarray from 0 to 4 = 4
Number of Fibonacci numbers in subarray from 0 to 4 = 5```

Time Complexity: The time complexity of each query and update is O(log n) and that of building the segment tree is O(n)

My Personal Notes arrow_drop_up