 Open in App
Not now

# Array Range Queries to count Powerful numbers with updates

• Last Updated : 07 Mar, 2022

Given an array of N integers, the task is to perform the following two operations on the given array:

query(L, R): Print the number of Powerful numbers in the subarray from L to R.
update(i, x) : update the value at index i to x, i.e arr[i] = x

A number N is said to be Powerful Number if, for every prime factor p of it, p2 also divides it.
Prerequisites: Powerful Number, Segment tree
Examples:

Input:
arr = {1, 12, 3, 8, 17, 9}
Query 1: query(L = 1, R = 4)
Query 2: update(i = 1, x = 9)
Query 3: query(L = 1, R = 4)
Output:

Explanation:
Query 1: Powerful numbers in range arr[1:4] is 8.
Query 2: Powerful numbers in range arr[1:4] after update operation is 9 and 8.

Approach:
Since we need to handle point updates and range queries so we will use a segment tree to solve the problem.

1. We will precompute all the Powerful numbers till the maximum value that arr[i] can take, say MAX
The time complexity of this operation will be O(MAX * sqrt(MAX))

2. Building the segment tree:
• The problem can be reduced to subarray sum using segment tree

• Now we can build the segment tree where the leaf nodes will represent 1(when a number is a Powerful number) or 0(when a number is not a powerful number). All the internal nodes will have the sum of both of its children.

• To update an element we need to look at the interval in which the element is and recurse accordingly on the left or the right child. If the element to be updated is a Powerful number then we update the leaf as 1, else 0.

4. Range Query:
• Whenever we get a query from L to R, then we can query the segment tree for the sum of nodes in range L to R, which in turn represents the number of Powerful numbers in the range L to R.

Below is the implementation of the above approach:

## C++

 `// C++ Program to find the number` `// of Powerful numbers in subarray` `// using segment tree` `#include ` `using` `namespace` `std;`   `#define MAX 100000`   `// Size of segment tree = 2^{log(MAX)+1}` `int` `tree[3 * MAX];` `int` `arr[MAX];` `bool` `powerful[MAX + 1];`   `// Function to check if the ` `// number is powerful` `bool` `isPowerful(``int` `n)` `{` `    ``// First divide the number` `    ``// repeatedly by 2` `    ``while` `(n % 2 == 0)` `    ``{` `        ``int` `power = 0;` `        ``while` `(n % 2 == 0)` `        ``{` `            ``n /= 2;` `            ``power++;` `        ``}`   `        ``// If only 2^1 divides ` `        ``// n (not higher powers),` `        ``// then return false` `        ``if` `(power == 1)` `            ``return` `false``;` `    ``}`   `    ``// If n is not a power of 2 then ` `    ``// this loop will execute` `    ``// repeat above process` `    ``for` `(``int` `factor = 3; factor ` `         ``<= ``sqrt``(n); factor += 2)` `    ``{` `        ``// Find highest power of ` `        ``// "factor" that divides n` `        ``int` `power = 0;` `        ``while` `(n % factor == 0)` `        ``{` `            ``n = n / factor;` `            ``power++;` `        ``}`   `        ``// If only factor^1 divides n ` `        ``// (not higher powers),` `        ``// then return false` `        ``if` `(power == 1)` `            ``return` `false``;` `    ``}`   `    ``// n must be 1 now if it is not ` `    ``// a prime numenr. Since prime ` `    ``// numbers are not powerful, ` `    ``// we return false if n is not 1.` `    ``return` `(n == 1);` `}`   `// Function to build the array` `void` `BuildArray(``int` `input[], ``int` `n)` `{` `    ``for` `(``int` `i = 0; i < n; i++)` `    ``{` `        ``// Check if input[i] is` `        ``// a Powerful number or not` `        ``if` `(powerful[input[i]])` `            ``arr[i] = 1;`   `        ``else` `            ``arr[i] = 0;` `    ``}` `    ``return``;`   `}`   `// A utility function to get the middle` `// index from corner indexes.` `int` `getMid(``int` `s, ``int` `e)` `{` `    ``return` `s + (e - s) / 2;` `}`   `/* A recursive function that constructs` ` ``Segment Tree for array[ss..se].`   `si --> 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]` `*/` `void` `constructSTUtil(``int` `si, ``int` `ss,` `                     ``int` `se)` `{` `    ``if` `(ss == se) {` `        ``// If there is one element ` `        ``// in array` `        ``tree[si] = arr[ss];` `        ``return``;` `    ``}`   `    ``// 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` `    ``else` `{` `        ``int` `mid = getMid(ss, se);` `        `  `        ``constructSTUtil(2 * si + 1, ` `                        ``ss, mid);` `        `  `        ``constructSTUtil(2 * si + 2, ` `                        ``mid + 1, se);` `        `  `        ``tree[si] = tree[2 * si + 1]` `                  ``+ tree[2 * si + 2];` `    ``}` `}`   `/* A recursive function to update the ` `nodes which have the given index` `in their range.`   `si --> 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]`   `ind --> Index of array to be updated`   `val --> The new value to be updated`   `*/` `void` `updateValueUtil(``int` `si, ``int` `ss, ``int` `se, ` `                     ``int` `idx, ``int` `val)` `{` `    ``// Leaf node` `    ``if` `(ss == se) {` `        ``tree[si] = tree[si] - arr[idx] + val;` `        ``arr[idx] = val;` `    ``}` `    ``else` `{` `        ``int` `mid = getMid(ss, se);` `        `  `        ``// If idx is in the left child,` `        ``// recurse on the left child` `        ``if` `(ss <= idx and idx <= mid)` `            ``updateValueUtil(2 * si + 1, ss,` `                            ``mid, idx, val);`   `        ``// If idx is in the right child,` `        ``// recurse on the right child` `        ``else` `            ``updateValueUtil(2 * si + 2, mid + 1, ` `                            ``se, idx, val);`   `        ``// Internal node will have the sum ` `        ``// of both of its children` `        ``tree[si] = tree[2 * si + 1]` `                   ``+ tree[2 * si + 2];` `    ``}` `}`   `/* A recursive function to get the number` `of Powerful numbers in a given ` `range of array indexes`   `si --> 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]` `l & r --> Starting and ending indexes of` `          ``query range`     ` ``*/` `int` `queryPowerfulUtil(``int` `si, ``int` `ss, ``int` `se, ` `                      ``int` `l, ``int` `r)` `{` `    ``// If segment of this node is` `    ``// outside the given range` `    ``if` `(r < ss or se < l) {` `        ``return` `0;` `    ``}` `    ``// If segment of this node is a part ` `    ``// of given range, then return the` `    ``// number of composites` `    ``// in the segment` `    ``if` `(l <= ss and se <= r) {` `        ``return` `tree[si];` `    ``}`   `    ``// If a part of this segment` `    ``// overlaps with the given range` `    ``int` `mid = getMid(ss, se);` `    ``int` `p1 = queryPowerfulUtil(2 * si + 1, ` `                               ``ss, mid, l,` `                               ``r);` `    ``int` `p2 = queryPowerfulUtil(2 * si + 2,` `                               ``mid + 1, ` `                               ``se, l, r);` `    ``return` `(p1 + p2);` `}`   `void` `queryPowerful(``int` `n, ``int` `l, ``int` `r)` `{` `    ``printf``(``"Number of Powerful numbers between %d to %d = %d\n"``,` `           ``l, r, queryPowerfulUtil(0, 0,` `                                   ``n - 1,` `                                   ``l, r));` `}`   `void` `updateValue(``int` `n, ``int` `ind, ``int` `val)` `{` `    ``// If val is a Powerful number` `    ``// we will update 1 in tree` `    ``if` `(powerful[val])` `        ``updateValueUtil(0, 0, n - 1,` `                        ``ind, 1);` `    ``else` `        ``updateValueUtil(0, 0, n - 1,` `                        ``ind, 0);` `}`   `void` `precomputePowerful()` `{`   `    ``memset``(powerful, ``false``, ` `           ``sizeof``(powerful));`   `    ``// Computing all Powerful ` `    ``// numbers till MAX` `    ``for` `(``int` `i = 1; i <= MAX; i++)` `    ``{` `        ``// If the number is ` `        ``// Powerful make ` `        ``// powerful[i] = true` `        ``if` `(isPowerful(i))` `            ``powerful[i] = ``true``;` `    ``}` `}`   `// Driver Code` `int` `main()` `{` `    ``// Precompute all the powerful ` `    ``// numbers till MAX` `    ``precomputePowerful();`   `    ``// Input array` `    ``int` `input[] = { 4, 5, 18, 27, 40, 144 };` `    `  `    ``// Size of Input array` `    ``int` `n = ``sizeof``(input) / ``sizeof``(input);`   `    ``// Build the array.` `    ``BuildArray(input, n);` `    `  `    ``// Build segment tree from ` `    ``// given array` `    ``constructSTUtil(0, 0, n - 1);`   `    ``// Query 1: Query(L = 0, R = 3)` `    ``int` `l = 0, r = 3;` `    ``queryPowerful(n, l, r);`   `    ``// Query 2: Update(i = 1, x = 9), ` `    ``// i.e Update input[i] to x` `    ``int` `i = 1;` `    ``int` `val = 9;` `    ``updateValue(n, i, val);`   `    ``// Query 3: Query(L = 0, R = 3)` `    ``queryPowerful(n, l, r);`     `    ``return` `0;` `}`

## Java

 `// Java program to find the number` `// of Powerful numbers in subarray` `// using segment tree` `import` `java.util.*;`   `class` `GFG{`   `static` `final` `int` `MAX = ``100000``;`   `// Size of segment tree = 2^{log(MAX)+1}` `static` `int` `[]tree = ``new` `int``[``3` `* MAX];` `static` `int` `[]arr = ``new` `int``[MAX];` `static` `boolean` `[]powerful = ``new` `boolean``[MAX + ``1``];`   `// Function to check if the ` `// number is powerful` `static` `boolean` `isPowerful(``int` `n)` `{` `    `  `    ``// First divide the number` `    ``// repeatedly by 2` `    ``while` `(n % ``2` `== ``0``)` `    ``{` `        ``int` `power = ``0``;` `        ``while` `(n % ``2` `== ``0``)` `        ``{` `            ``n /= ``2``;` `            ``power++;` `        ``}`   `        ``// If only 2^1 divides ` `        ``// n (not higher powers),` `        ``// then return false` `        ``if` `(power == ``1``)` `            ``return` `false``;` `    ``}`   `    ``// If n is not a power of 2 then ` `    ``// this loop will execute` `    ``// repeat above process` `    ``for``(``int` `factor = ``3``; ` `            ``factor <= Math.sqrt(n);` `            ``factor += ``2``)` `    ``{` `        `  `        ``// Find highest power of ` `        ``// "factor" that divides n` `        ``int` `power = ``0``;` `        ``while` `(n % factor == ``0``)` `        ``{` `            ``n = n / factor;` `            ``power++;` `        ``}`   `        ``// If only factor^1 divides n ` `        ``// (not higher powers),` `        ``// then return false` `        ``if` `(power == ``1``)` `            ``return` `false``;` `    ``}`   `    ``// n must be 1 now if it is not ` `    ``// a prime numenr. Since prime ` `    ``// numbers are not powerful, ` `    ``// we return false if n is not 1.` `    ``return` `(n == ``1``);` `}`   `// Function to build the array` `static` `void` `BuildArray(``int` `input[], ``int` `n)` `{` `    ``for``(``int` `i = ``0``; i < n; i++)` `    ``{` `        `  `        ``// Check if input[i] is` `        ``// a Powerful number or not` `        ``if` `(powerful[input[i]])` `            ``arr[i] = ``1``;`   `        ``else` `            ``arr[i] = ``0``;` `    ``}` `    ``return``;` `}`   `// A utility function to get the middle` `// index from corner indexes.` `static` `int` `getMid(``int` `s, ``int` `e)` `{` `    ``return` `s + (e - s) / ``2``;` `}`   `/* A recursive function that constructs` `Segment Tree for array[ss..se].`   `si -. 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]` `*/` `static` `void` `constructSTUtil(``int` `si, ``int` `ss,` `                            ``int` `se)` `{` `    ``if` `(ss == se) ` `    ``{` `        `  `        ``// If there is one element ` `        ``// in array` `        ``tree[si] = arr[ss];` `        ``return``;` `    ``}`   `    ``// 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` `    ``else` `    ``{` `        ``int` `mid = getMid(ss, se);` `        `  `        ``constructSTUtil(``2` `* si + ``1``, ` `                        ``ss, mid);` `        `  `        ``constructSTUtil(``2` `* si + ``2``, ` `                        ``mid + ``1``, se);` `        `  `        ``tree[si] = tree[``2` `* si + ``1``] +` `                   ``tree[``2` `* si + ``2``];` `    ``}` `}`   `/* A recursive function to update the ` `nodes which have the given index` `in their range.`   `si -. 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]`   `ind -. Index of array to be updated`   `val -. The new value to be updated`   `*/` `static` `void` `updateValueUtil(``int` `si, ``int` `ss, ``int` `se, ` `                            ``int` `idx, ``int` `val)` `{` `    `  `    ``// Leaf node` `    ``if` `(ss == se) ` `    ``{` `        ``tree[si] = tree[si] - arr[idx] + val;` `        ``arr[idx] = val;` `    ``}` `    ``else` `    ``{` `        ``int` `mid = getMid(ss, se);` `        `  `        ``// If idx is in the left child,` `        ``// recurse on the left child` `        ``if` `(ss <= idx && idx <= mid)` `            ``updateValueUtil(``2` `* si + ``1``, ss,` `                            ``mid, idx, val);`   `        ``// If idx is in the right child,` `        ``// recurse on the right child` `        ``else` `            ``updateValueUtil(``2` `* si + ``2``, mid + ``1``, ` `                            ``se, idx, val);`   `        ``// Internal node will have the sum ` `        ``// of both of its children` `        ``tree[si] = tree[``2` `* si + ``1``] + ` `                   ``tree[``2` `* si + ``2``];` `    ``}` `}`   `/* A recursive function to get the number` `of Powerful numbers in a given ` `range of array indexes`   `si -. 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]` `l & r -. Starting and ending indexes of` `        ``query range`   `*/` `static` `int` `queryPowerfulUtil(``int` `si, ``int` `ss,` `                             ``int` `se, ``int` `l, ``int` `r)` `{` `    `  `    ``// If segment of this node is` `    ``// outside the given range` `    ``if` `(r < ss || se < l)` `    ``{` `        ``return` `0``;` `    ``}` `    `  `    ``// If segment of this node is a part ` `    ``// of given range, then return the` `    ``// number of composites` `    ``// in the segment` `    ``if` `(l <= ss && se <= r) ` `    ``{` `        ``return` `tree[si];` `    ``}`   `    ``// If a part of this segment` `    ``// overlaps with the given range` `    ``int` `mid = getMid(ss, se);` `    ``int` `p1 = queryPowerfulUtil(``2` `* si + ``1``, ` `                               ``ss, mid, l,` `                               ``r);` `    ``int` `p2 = queryPowerfulUtil(``2` `* si + ``2``,` `                                  ``mid + ``1``, ` `                                 ``se, l, r);` `    ``return` `(p1 + p2);` `}`   `static` `void` `queryPowerful(``int` `n, ``int` `l, ``int` `r)` `{` `    ``System.out.printf(``"Number of Powerful numbers "` `+ ` `                      ``"between %d to %d = %d\n"``, l, r,` `                      ``queryPowerfulUtil(``0``, ``0``, n - ``1``,` `                                        ``l, r));` `}`   `static` `void` `updateValue(``int` `n, ``int` `ind, ``int` `val)` `{` `    `  `    ``// If val is a Powerful number` `    ``// we will update 1 in tree` `    ``if` `(powerful[val])` `        ``updateValueUtil(``0``, ``0``, n - ``1``,` `                        ``ind, ``1``);` `    ``else` `        ``updateValueUtil(``0``, ``0``, n - ``1``,` `                        ``ind, ``0``);` `}`   `static` `void` `precomputePowerful()` `{` `    ``Arrays.fill(powerful, ``false``);` `    `  `    ``// Computing all Powerful ` `    ``// numbers till MAX` `    ``for``(``int` `i = ``1``; i <= MAX; i++)` `    ``{` `        `  `        ``// If the number is ` `        ``// Powerful make ` `        ``// powerful[i] = true` `        ``if` `(isPowerful(i))` `            ``powerful[i] = ``true``;` `    ``}` `}`   `// Driver Code` `public` `static` `void` `main(String[] args)` `{` `    `  `    ``// Precompute all the powerful ` `    ``// numbers till MAX` `    ``precomputePowerful();`   `    ``// Input array` `    ``int` `input[] = { ``4``, ``5``, ``18``, ``27``, ``40``, ``144` `};` `    `  `    ``// Size of Input array` `    ``int` `n = input.length;`   `    ``// Build the array.` `    ``BuildArray(input, n);` `    `  `    ``// Build segment tree from ` `    ``// given array` `    ``constructSTUtil(``0``, ``0``, n - ``1``);`   `    ``// Query 1: Query(L = 0, R = 3)` `    ``int` `l = ``0``, r = ``3``;` `    ``queryPowerful(n, l, r);`   `    ``// Query 2: Update(i = 1, x = 9), ` `    ``// i.e Update input[i] to x` `    ``int` `i = ``1``;` `    ``int` `val = ``9``;` `    ``updateValue(n, i, val);`   `    ``// Query 3: Query(L = 0, R = 3)` `    ``queryPowerful(n, l, r);` `}` `}`   `// This code is contributed by amal kumar choubey`

## Python3

 `# Python3 program to find the number` `# of Powerful numbers in subarray` `# using segment tree` `import` `math` `MAX` `=` `100000` `  `  `# Size of segment tree = 2^{log(MAX)+1}` `tree ``=` `[``0``]``*``(``3` `*` `MAX``)` `arr ``=` `[``0``]``*``(``MAX``)` `powerful ``=` `[``False``]``*``(``MAX` `+` `1``)`   `# Function to check if the` `# number is powerful` `def` `isPowerful(n):` `  `  `    ``# First divide the number` `    ``# repeatedly by 2` `    ``while` `(n ``%` `2` `=``=` `0``):` `        ``power ``=` `0` `        ``while` `(n ``%` `2` `=``=` `0``):` `            ``n ``=` `int``(n ``/` `2``)` `            ``power ``+``=` `1`   `        ``# If only 2^1 divides` `        ``# n (not higher powers),` `        ``# then return false` `        ``if` `(power ``=``=` `1``):` `            ``return` `False`   `    ``# If n is not a power of 2 then` `    ``# this loop will execute` `    ``# repeat above process` `    ``for` `factor ``in` `range``(``3``, ``int``(math.sqrt(n)) ``+` `1``, ``2``):` `      `  `        ``# Find highest power of` `        ``# "factor" that divides n` `        ``power ``=` `0` `        ``while` `(n ``%` `factor ``=``=` `0``):` `            ``n ``=` `int``(n ``/` `factor)` `            ``power ``+``=` `1`   `        ``# If only factor^1 divides n` `        ``# (not higher powers),` `        ``# then return false` `        ``if` `(power ``=``=` `1``):` `            ``return` `False`   `    ``# n must be 1 now if it is not` `    ``# a prime number. Since prime` `    ``# numbers are not powerful,` `    ``# we return false if n is not 1.` `    ``return` `(n ``=``=` `1``)`   `# Function to build the array` `def` `BuildArray(``Input``, n):` `    ``for` `i ``in` `range``(n):` `      `  `        ``# Check if input[i] is` `        ``# a Powerful number or not` `        ``if` `(powerful[``Input``[i]]):` `            ``arr[i] ``=` `1` `        ``else``:` `            ``arr[i] ``=` `0` `    ``return`   `# A utility function to get the middle` `# index from corner indexes.` `def` `getMid(s, e):` `    ``return` `s ``+` `int``((e ``-` `s) ``/` `2``)`   `""" A recursive function that constructs` `Segment Tree for array[ss..se].`   `si -. 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]` `"""` `def` `constructSTUtil(si, ss, se):` `    ``if` `(ss ``=``=` `se):` `        ``# If there is one element` `        ``# in array` `        ``tree[si] ``=` `arr[ss]` `        ``return`   `    ``# 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` `    ``else``:` `        ``mid ``=` `getMid(ss, se)` `        ``constructSTUtil(``2` `*` `si ``+` `1``, ss, mid)` `        ``constructSTUtil(``2` `*` `si ``+` `2``, mid ``+` `1``, se)` `        ``tree[si] ``=` `tree[``2` `*` `si ``+` `1``] ``+` `tree[``2` `*` `si ``+` `2``]`   `""" A recursive function to update the` `nodes which have the given index` `in their range.`   `si -. 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]`   `ind -. Index of array to be updated`   `val -. The new value to be updated`   `"""` `def` `updateValueUtil(si, ss, se, idx, val):` `    ``# Leaf node` `    ``if` `(ss ``=``=` `se):` `        ``tree[si] ``=` `tree[si] ``-` `arr[idx] ``+` `val` `        ``arr[idx] ``=` `val` `    ``else``:` `        ``mid ``=` `getMid(ss, se)` `        ``# If idx is in the left child,` `        ``# recurse on the left child` `        ``if` `(ss <``=` `idx ``and` `idx <``=` `mid):` `            ``updateValueUtil(``2` `*` `si ``+` `1``, ss, mid, idx, val)`   `        ``# If idx is in the right child,` `        ``# recurse on the right child` `        ``else``:` `            ``updateValueUtil(``2` `*` `si ``+` `2``, mid ``+` `1``, se, idx, val)`   `        ``# Internal node will have the sum` `        ``# of both of its children` `        ``tree[si] ``=` `tree[``2` `*` `si ``+` `1``] ``+` `tree[``2` `*` `si ``+` `2``]`   `""" A recursive function to get the number` `of Powerful numbers in a given` `range of array indexes`   `si -. 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]` `l & r -. Starting and ending indexes of` `        ``query range` `"""` `def` `queryPowerfulUtil(si, ss, se, l, r):` `  `  `    ``# If segment of this node is` `    ``# outside the given range` `    ``if` `(r < ss ``or` `se < l):` `        ``return` `0`   `    ``# If segment of this node is a part` `    ``# of given range, then return the` `    ``# number of composites` `    ``# in the segment` `    ``if` `(l <``=` `ss ``and` `se <``=` `r):` `        ``return` `tree[si]`   `    ``# If a part of this segment` `    ``# overlaps with the given range` `    ``mid ``=` `getMid(ss, se)` `    ``p1 ``=` `queryPowerfulUtil(``2` `*` `si ``+` `1``, ss, mid, l, r)` `    ``p2 ``=` `queryPowerfulUtil(``2` `*` `si ``+` `2``, mid ``+` `1``, se, l, r)` `    ``return` `(p1 ``+` `p2)`   `def` `queryPowerful(n, l, r):` `    ``print``(``"Number of Powerful numbers between"``, l, ``"to"``, r, ``"="``, queryPowerfulUtil(``0``, ``0``, n ``-` `1``, l, r))`   `def` `updateValue(n, ind, val):` `  `  `    ``# If val is a Powerful number` `    ``# we will update 1 in tree` `    ``if` `(powerful[val]):` `        ``updateValueUtil(``0``, ``0``, n ``-` `1``, ind, ``1``)` `    ``else``:` `        ``updateValueUtil(``0``, ``0``, n ``-` `1``, ind, ``0``)`   `def` `precomputePowerful():` `    ``for` `i ``in` `range``(``MAX` `+` `1``):` `        ``powerful[i] ``=` `False`   `    ``# Computing all Powerful` `    ``# numbers till MAX` `    ``for` `i ``in` `range``(``1``, ``MAX` `+` `1``):` `      `  `        ``# If the number is` `        ``# Powerful make` `        ``# powerful[i] = true` `        ``if` `(isPowerful(i)):` `            ``powerful[i] ``=` `True`   `# Precompute all the powerful` `# numbers till MAX` `precomputePowerful()`   `# Input array` `Input` `=` `[ ``4``, ``5``, ``18``, ``27``, ``40``, ``144` `]` ` `  `# Size of Input array` `n ``=` `len``(``Input``)`   `# Build the array.` `BuildArray(``Input``, n)` ` `  `# Build segment tree from` `# given array` `constructSTUtil(``0``, ``0``, n ``-` `1``)`   `# Query 1: Query(L = 0, R = 3)` `l, r ``=` `0``, ``3` `queryPowerful(n, l, r)`   `# Query 2: Update(i = 1, x = 9),` `# i.e Update input[i] to x` `i ``=` `1` `val ``=` `9` `updateValue(n, i, val)`   `# Query 3: Query(L = 0, R = 3)` `queryPowerful(n, l, r)`   `# This code is contributed by divyesh072019.`

## C#

 `// C# program to find the number` `// of Powerful numbers in subarray` `// using segment tree` `using` `System;` `class` `GFG{`   `static` `readonly` `int` `MAX = 100000;`   `// Size of segment tree = 2^{log(MAX)+1}` `static` `int` `[]tree = ``new` `int``[3 * MAX];` `static` `int` `[]arr = ``new` `int``[MAX];` `static` `bool` `[]powerful = ``new` `bool``[MAX + 1];`   `// Function to check if the ` `// number is powerful` `static` `bool` `isPowerful(``int` `n)` `{` `    `  `    ``// First divide the number` `    ``// repeatedly by 2` `    ``while` `(n % 2 == 0)` `    ``{` `        ``int` `power = 0;` `        ``while` `(n % 2 == 0)` `        ``{` `            ``n /= 2;` `            ``power++;` `        ``}`   `        ``// If only 2^1 divides ` `        ``// n (not higher powers),` `        ``// then return false` `        ``if` `(power == 1)` `            ``return` `false``;` `    ``}`   `    ``// If n is not a power of 2 then ` `    ``// this loop will execute` `    ``// repeat above process` `    ``for``(``int` `factor = 3; ` `            ``factor <= Math.Sqrt(n);` `            ``factor += 2)` `    ``{` `        `  `        ``// Find highest power of ` `        ``// "factor" that divides n` `        ``int` `power = 0;` `        ``while` `(n % factor == 0)` `        ``{` `            ``n = n / factor;` `            ``power++;` `        ``}`   `        ``// If only factor^1 divides n ` `        ``// (not higher powers),` `        ``// then return false` `        ``if` `(power == 1)` `            ``return` `false``;` `    ``}`   `    ``// n must be 1 now if it is not ` `    ``// a prime numenr. Since prime ` `    ``// numbers are not powerful, ` `    ``// we return false if n is not 1.` `    ``return` `(n == 1);` `}`   `// Function to build the array` `static` `void` `BuildArray(``int` `[]input, ``int` `n)` `{` `    ``for``(``int` `i = 0; i < n; i++)` `    ``{` `        `  `        ``// Check if input[i] is` `        ``// a Powerful number or not` `        ``if` `(powerful[input[i]])` `            ``arr[i] = 1;`   `        ``else` `            ``arr[i] = 0;` `    ``}` `    ``return``;` `}`   `// A utility function to get the middle` `// index from corner indexes.` `static` `int` `getMid(``int` `s, ``int` `e)` `{` `    ``return` `s + (e - s) / 2;` `}`   `/* A recursive function that constructs` `Segment Tree for array[ss..se].`   `si -. 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]` `*/` `static` `void` `constructSTUtil(``int` `si, ``int` `ss,` `                            ``int` `se)` `{` `    ``if` `(ss == se) ` `    ``{` `        `  `        ``// If there is one element ` `        ``// in array` `        ``tree[si] = arr[ss];` `        ``return``;` `    ``}`   `    ``// 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` `    ``else` `    ``{` `        ``int` `mid = getMid(ss, se);` `        `  `        ``constructSTUtil(2 * si + 1, ` `                        ``ss, mid);` `        `  `        ``constructSTUtil(2 * si + 2, ` `                        ``mid + 1, se);` `        `  `        ``tree[si] = tree[2 * si + 1] +` `                   ``tree[2 * si + 2];` `    ``}` `}`   `/* A recursive function to update the ` `nodes which have the given index` `in their range.`   `si -. 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]`   `ind -. Index of array to be updated`   `val -. The new value to be updated`   `*/` `static` `void` `updateValueUtil(``int` `si, ``int` `ss, ``int` `se, ` `                            ``int` `idx, ``int` `val)` `{` `    `  `    ``// Leaf node` `    ``if` `(ss == se) ` `    ``{` `        ``tree[si] = tree[si] - arr[idx] + val;` `        ``arr[idx] = val;` `    ``}` `    ``else` `    ``{` `        ``int` `mid = getMid(ss, se);` `        `  `        ``// If idx is in the left child,` `        ``// recurse on the left child` `        ``if` `(ss <= idx && idx <= mid)` `            ``updateValueUtil(2 * si + 1, ss,` `                            ``mid, idx, val);`   `        ``// If idx is in the right child,` `        ``// recurse on the right child` `        ``else` `            ``updateValueUtil(2 * si + 2, mid + 1, ` `                            ``se, idx, val);`   `        ``// Internal node will have the sum ` `        ``// of both of its children` `        ``tree[si] = tree[2 * si + 1] + ` `                   ``tree[2 * si + 2];` `    ``}` `}`   `/* A recursive function to get the number` `of Powerful numbers in a given ` `range of array indexes`   `si -. 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]` `l & r -. Starting and ending indexes of` `        ``query range`   `*/` `static` `int` `queryPowerfulUtil(``int` `si, ``int` `ss,` `                             ``int` `se, ``int` `l, ``int` `r)` `{` `    `  `    ``// If segment of this node is` `    ``// outside the given range` `    ``if` `(r < ss || se < l)` `    ``{` `        ``return` `0;` `    ``}` `    `  `    ``// If segment of this node is a part ` `    ``// of given range, then return the` `    ``// number of composites` `    ``// in the segment` `    ``if` `(l <= ss && se <= r) ` `    ``{` `        ``return` `tree[si];` `    ``}`   `    ``// If a part of this segment` `    ``// overlaps with the given range` `    ``int` `mid = getMid(ss, se);` `    ``int` `p1 = queryPowerfulUtil(2 * si + 1, ` `                               ``ss, mid, l,` `                               ``r);` `    ``int` `p2 = queryPowerfulUtil(2 * si + 2,` `                                  ``mid + 1, ` `                                 ``se, l, r);` `    ``return` `(p1 + p2);` `}`   `static` `void` `queryPowerful(``int` `n, ``int` `l, ``int` `r)` `{` `    ``Console.WriteLine(``"Number of Powerful numbers "` `+ ` `                      ``"between "` `+ l +``" to "``+r+``" = "``+` `                      ``queryPowerfulUtil(0, 0, n - 1,` `                                        ``l, r));` `}`   `static` `void` `updateValue(``int` `n, ``int` `ind, ``int` `val)` `{` `    `  `    ``// If val is a Powerful number` `    ``// we will update 1 in tree` `    ``if` `(powerful[val])` `        ``updateValueUtil(0, 0, n - 1,` `                        ``ind, 1);` `    ``else` `        ``updateValueUtil(0, 0, n - 1,` `                        ``ind, 0);` `}`   `static` `void` `precomputePowerful()` `{` `   `  `    ``for``(``int` `i = 0; i <= MAX; i++)` `        ``powerful[i] = ``false``;` `    `  `    ``// Computing all Powerful ` `    ``// numbers till MAX` `    ``for``(``int` `i = 1; i <= MAX; i++)` `    ``{` `        `  `        ``// If the number is ` `        ``// Powerful make ` `        ``// powerful[i] = true` `        ``if` `(isPowerful(i))` `            ``powerful[i] = ``true``;` `    ``}` `}`   `// Driver Code` `public` `static` `void` `Main(String[] args)` `{` `    `  `    ``// Precompute all the powerful ` `    ``// numbers till MAX` `    ``precomputePowerful();`   `    ``// Input array` `    ``int` `[]input = { 4, 5, 18, 27, 40, 144 };` `    `  `    ``// Size of Input array` `    ``int` `n = input.Length;`   `    ``// Build the array.` `    ``BuildArray(input, n);` `    `  `    ``// Build segment tree from ` `    ``// given array` `    ``constructSTUtil(0, 0, n - 1);`   `    ``// Query 1: Query(L = 0, R = 3)` `    ``int` `l = 0, r = 3;` `    ``queryPowerful(n, l, r);`   `    ``// Query 2: Update(i = 1, x = 9), ` `    ``// i.e Update input[i] to x` `    ``int` `i = 1;` `    ``int` `val = 9;` `    ``updateValue(n, i, val);`   `    ``// Query 3: Query(L = 0, R = 3)` `    ``queryPowerful(n, l, r);` `}` `}`   `// This code is contributed by Rohit_ranjan`

## Javascript

 ``

Output:

```Number of Powerful numbers between 0 to 3 = 2
Number of Powerful numbers between 0 to 3 = 3```

Time Complexity: O(logN) per query

My Personal Notes arrow_drop_up
Related Articles