# Wavelet Trees | Introduction

Last Updated : 28 Apr, 2023

A wavelet tree is a data structure that recursively partitions a stream into two parts until we’re left with homogeneous data. The name derives from an analogy with the wavelet transform for signals, which recursively decomposes a signal into low-frequency and high-frequency components. Wavelet trees can be used to answer range queries efficiently.
Consider the problem to find number of elements in a range [L, R] of a given array A which are less than x. One way to solve this problem efficiently is using Persistent Segment Tree data structure. But we can also solve this easily using Wavelet Trees. Let us see how!

Constructing Wavelet TreesEvery node in a wavelet tree is represented by an array which is the subsequence of original array and a range [L, R]. Here [L, R] is the range in which elements of array falls. That is, ‘R’ denotes maximum element in the array and ‘L’ denotes the smallest element. So, the root node will contain the original array in which elements are in range [L, R]. Now we will calculate the middle of the range [L, R] and stable partition the array in two halves for the left and right childs. Therefore, the left child will contains elements that lies in range [L, mid] and right child will contain elements that lies in the range [mid+1, R].
Suppose we are given an array of integers. Now we compute the mid (Max + Min / 2) and form two children.
Left Children: Integers less than/equal to Mid
Right Children: Integers greater than Mid
We recursively perform this operation until all node of similar elements are formed.
Given array : 0 0 9 1 2 1 7 6 4 8 9 4 3 7 5 9 2 7 0 5 1 0

To construct a Wavelet Tree, let us see what will we need to store at each node. So at each node of the tree, we will store two arrays say S[] and freq[]. The array S[] will be a subsequence of the original array A[] and the array freq[] will store the count of the elements that will go to left and right childs of the node. That is, freq[i] will denote the count of elements from the first i elements of S[] that will go to left child. Therefore, count of elements that will go to right child can be easily calculated as (i – freq[i]).
Below example shows how to maintain freq[] array:

```Array : 1 5 2 6 4 4
Mid = (1 + 6) / 2 = 3
Left Child : 1 2
Right Child : 5 6 4 4```

To maintain frequency array, we will check if the element is less than Mid or not. If yes, then we will add 1 to last element of frequency array, else 0 and push back again.
For, above array :
Freq array :{1, 1, 2, 2, 2, 2}
It implies 1 element will go to left child of this node from index 1 and 2, and 2 elements will go to left child from indices 3 to 6. This can be easily depicted from the above given array.
To compute the number of elements moving to right subtree, we subtract freq[i] from i.

```From index 1, 0 elements go to right subtree.
From index 2, 1 element go to right subtree.
From index 3, 1 element go to right subtree.
From index 4, 2 elements go to right subtree.
From index 5, 3 elements go to right subtree.
From index 6, 4 elements go to right subtree.```

We can use the stable_partition function and lambda expression in C++ STL to easily stable partition the array around a pivot without distorting the order of elements in original sequence. It is highly recommended to go through the stable_partition and lambda expression articles before moving onto implementation.
Below is the implementation of construction of Wavelet Trees:

## CPP

 `// CPP code to implement wavelet trees` `#include ` `using` `namespace` `std;` `#define N 100000`   `// Given array` `int` `arr[N];`   `// wavelet tree class` `class` `wavelet_tree {` `public``:` `    ``// Range to elements` `    ``int` `low, high;`   `    ``// Left and Right children` `    ``wavelet_tree *l, *r;`   `    ``vector<``int``> freq;`   `    ``// Default constructor` `    ``// Array is in range [x, y]` `    ``// Indices are in range [from, to]` `    ``wavelet_tree(``int``* from, ``int``* to, ``int` `x, ``int` `y)` `    ``{` `        ``// Initialising low and high` `        ``low = x, high = y;`   `        ``// Array is of 0 length` `        ``if` `(from >= to)` `            ``return``;`   `        ``// Array is homogeneous` `        ``// Example : 1 1 1 1 1` `        ``if` `(high == low) {`   `            ``// Assigning storage to freq array` `            ``freq.reserve(to - from + 1);`   `            ``// Initialising the Freq array` `            ``freq.push_back(0);`   `            ``// Assigning values` `            ``for` `(``auto` `it = from; it != to; it++)`   `                ``// freq will be increasing as there'll` `                ``// be no further sub-tree` `                ``freq.push_back(freq.back() + 1);`   `            ``return``;` `        ``}`   `        ``// Computing mid` `        ``int` `mid = (low + high) / 2;`   `        ``// Lambda function to check if a number is` `        ``// less than or equal to mid` `        ``auto` `lessThanMid` `            ``= [mid](``int` `x) { ``return` `x <= mid; };`   `        ``// Assigning storage to freq array` `        ``freq.reserve(to - from + 1);`   `        ``// Initialising the freq array` `        ``freq.push_back(0);`   `        ``// Assigning value to freq array` `        ``for` `(``auto` `it = from; it != to; it++)`   `            ``// If lessThanMid returns 1(true), we add` `            ``// 1 to previous entry. Otherwise, we add` `            ``// 0 (element goes to right sub-tree)` `            ``freq.push_back(freq.back() + lessThanMid(*it));`   `        ``// std::stable_partition partitions the array w.r.t` `        ``// Mid` `        ``auto` `pivot` `            ``= stable_partition(from, to, lessThanMid);`   `        ``// Left sub-tree's object` `        ``l = ``new` `wavelet_tree(from, pivot, low, mid);`   `        ``// Right sub-tree's object` `        ``r = ``new` `wavelet_tree(pivot, to, mid + 1, high);` `    ``}` `};`   `// Driver code` `int` `main()` `{` `    ``int` `size = 5, high = INT_MIN;` `    ``int` `arr[] = { 1, 2, 3, 4, 5 };` `    ``for` `(``int` `i = 0; i < size; i++)` `        ``high = max(high, arr[i]);`   `    ``// Object of class wavelet tree` `    ``wavelet_tree obj(arr, arr + size, 1, high);`   `    ``return` `0;` `}`

## Java

 `// JAVA code to implement wavelet trees` `import` `java.util.*;`   `class` `WaveletTree {` `    ``int` `low, high;` `    ``WaveletTree l, r;` `    ``List freq;`   `    ``public` `WaveletTree(``int``[] arr, ``int` `low, ``int` `high)` `    ``{` `        ``// Store the range of values in the tree` `        ``this``.low = low;` `        ``this``.high = high;`   `        ``// If there is only one element, create a list with` `        ``// a single element` `        ``if` `(low == high) {` `            ``freq = ``new` `ArrayList<>();` `            ``freq.add(``0``);` `            ``for` `(``int` `i = ``0``; i < arr.length; i++) {` `                ``freq.add(freq.get(i) + ``1``);` `            ``}` `            ``return``;` `        ``}`   `        ``// Split the input array into two based on the` `        ``// midpoint of the range` `        ``int` `mid = (low + high) / ``2``;` `        ``freq = ``new` `ArrayList<>();` `        ``freq.add(``0``);` `        ``int``[] leftArr = ``new` `int``[arr.length];` `        ``int``[] rightArr = ``new` `int``[arr.length];` `        ``int` `leftIndex = ``0``, rightIndex = ``0``;` `        ``for` `(``int` `i = ``0``; i < arr.length; i++) {` `            ``if` `(arr[i] <= mid) {` `                ``leftArr[leftIndex++] = arr[i];` `                ``freq.add(freq.get(i) + ``1``);` `            ``}` `            ``else` `{` `                ``rightArr[rightIndex++] = arr[i];` `                ``freq.add(freq.get(i));` `            ``}` `        ``}`   `        ``// Recursively create Wavelet Trees for the left and` `        ``// right arrays` `        ``l = ``new` `WaveletTree(leftArr, low, mid);` `        ``r = ``new` `WaveletTree(rightArr, mid + ``1``, high);` `    ``}` `}` `// Driver code` `public` `class` `Main {` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``int` `size = ``5``, high = Integer.MIN_VALUE;` `        ``int``[] arr = { ``1``, ``2``, ``3``, ``4``, ``5` `};` `        ``for` `(``int` `i = ``0``; i < size; i++)` `            ``high = Math.max(high, arr[i]);` `        ``// Object of class wavelet tree` `        ``WaveletTree obj = ``new` `WaveletTree(arr, ``1``, high);` `    ``}` `}`

## Javascript

 `// javascript code to implement wavelet trees` `const N = 100000;` `const INT_MIN = -2147483647;`     `// wavelet tree class` `class wavelet_tree {`   `    ``constructor(arr, low, high) {` `        ``// Store the range of values in the tree` `        ``this``.low = low;` `        ``this``.high = high;`   `        ``// If there is only one element, create a list with a single element` `        ``if` `(low == high) {` `            ``this``.freq = [];` `            ``this``.freq.push(0);` `            ``for` `(let i = 0; i < arr.length; i++) {` `                ``this``.freq.push(``this``.freq[i] + 1);` `            ``}` `            ``return``;` `        ``}` `        `  `        ``// Split the input array into two based on the midpoint of the range` `        ``let mid = Math.floor((low + high) / 2);` `        ``this``.freq = [];` `        ``this``.freq.push(0);` `        ``let leftArr = ``new` `Array(arr.length);` `        ``let rightArr = ``new` `Array(arr.length);` `        ``let leftIndex = 0, rightIndex = 0;` `        ``for` `(let i = 0; i < arr.length; i++) {` `            ``if` `(arr[i] <= mid) {` `                ``leftArr[leftIndex++] = arr[i];` `                ``this``.freq.push(``this``.freq[i] + 1);` `            ``} ``else` `{` `                ``rightArr[rightIndex++] = arr[i];` `                ``this``.freq.push(``this``.freq[i]);` `            ``}` `        ``}`   `        ``// Recursively create Wavelet Trees for the left and right arrays` `        ``this``.l = ``new` `wavelet_tree(leftArr, low, mid);` `        ``this``.r = ``new` `wavelet_tree(rightArr, mid + 1, high);` `    ``}` `}`     `let size = 5;` `let high = INT_MIN;    ` `let arr = [1 , 2, 3, 4, 5]; ` `for` `(let i = 0; i < size; i++) ` `    ``high = Math.max(high, arr[i]);    `   `// Object of class wavelet tree` `let obj = ``new` `wavelet_tree(arr, 1, high);`   `// The code is contributed by Nidhi goel.`

## Python3

 `class` `WaveletTree:` `  ``# Constructor function` `    ``def` `__init__(``self``, from_idx, to_idx, low, high, arr):` `      ``# If the array is homogeneous, store the frequency and return` `        ``self``.low ``=` `low` `        ``self``.high ``=` `high` `        ``if` `from_idx >``=` `to_idx:` `            ``return` `        ``if` `self``.high ``=``=` `self``.low:` `            ``self``.freq ``=` `[``0``] ``*` `(to_idx ``-` `from_idx ``+` `2``)` `            ``for` `i ``in` `range``(from_idx, to_idx ``+` `1``):` `                ``self``.freq[i ``-` `from_idx ``+` `1``] ``=` `self``.freq[i ``-` `from_idx] ``+` `1` `            ``return` `        ``mid ``=` `(``self``.low ``+` `self``.high) ``/``/` `2` `         ``# Compute frequency array` `        ``self``.freq ``=` `[``0``] ``*` `(to_idx ``-` `from_idx ``+` `2``)` `        ``for` `i ``in` `range``(from_idx, to_idx ``+` `1``):` `            ``self``.freq[i ``-` `from_idx ``+` `1``] ``=` `self``.freq[i ``-` `from_idx] ``+` `(arr[i] <``=` `mid)` `        ``pivot ``=` `from_idx` `        ``while` `pivot <``=` `to_idx ``and` `arr[pivot] <``=` `mid:` `            ``pivot ``+``=` `1` `        ``self``.l ``=` `WaveletTree(from_idx, pivot ``-` `1``, ``self``.low, mid, arr)` `        ``self``.r ``=` `WaveletTree(pivot, to_idx, mid ``+` `1``, ``self``.high, arr)`   `    ``def` `kOrLess(``self``, l, r, k):` `        ``if` `l > r ``or` `k < ``self``.low:` `            ``return` `0` `        ``if` `self``.high <``=` `k:` `            ``return` `r ``-` `l ``+` `1` `        ``LtCount ``=` `self``.freq[l ``-` `1``]` `        ``RtCount ``=` `self``.freq[r]` `        ``return` `(` `            ``self``.l.kOrLess(LtCount ``+` `1``, RtCount, k) ``+` `            ``self``.r.kOrLess(l ``-` `LtCount, r ``-` `RtCount, k)` `        ``)`   `# Example usage` `size ``=` `5` `high ``=` `float``(``'-inf'``)`   `# Array : 1 2 3 4 5` `arr ``=` `[``1``, ``2``, ``3``, ``4``, ``5``]`   `for` `i ``in` `range``(size):` `    ``high ``=` `max``(high, arr[i])`   `# Object of class wavelet tree` `obj ``=` `WaveletTree(``0``, size ``-` `1``, ``1``, high, arr)`   `# count of elements less than 2 in range [1,3]` `print``(obj.kOrLess(``1``, ``3``, ``2``)) `

## C#

 `using` `System;` `using` `System.Collections.Generic;`   `class` `WaveletTree {` `    ``int` `low, high;` `    ``WaveletTree l, r;` `    ``List<``int``> freq;`   `    ``public` `WaveletTree(``int``[] arr, ``int` `low, ``int` `high)` `    ``{` `        ``// Store the range of values in the tree` `        ``this``.low = low;` `        ``this``.high = high;`   `        ``// If there is only one element, create a list with` `        ``// a single element` `        ``if` `(low == high) {` `            ``freq = ``new` `List<``int``>();` `            ``freq.Add(0);` `            ``for` `(``int` `i = 0; i < arr.Length; i++) {` `                ``freq.Add(freq[i] + 1);` `            ``}` `            ``return``;` `        ``}`   `        ``// Split the input array into two based on the` `        ``// midpoint of the range` `        ``int` `mid = (low + high) / 2;` `        ``freq = ``new` `List<``int``>();` `        ``freq.Add(0);` `        ``int``[] leftArr = ``new` `int``[arr.Length];` `        ``int``[] rightArr = ``new` `int``[arr.Length];` `        ``int` `leftIndex = 0, rightIndex = 0;` `        ``for` `(``int` `i = 0; i < arr.Length; i++) {` `            ``if` `(arr[i] <= mid) {` `                ``leftArr[leftIndex++] = arr[i];` `                ``freq.Add(freq[i] + 1);` `            ``}` `            ``else` `{` `                ``rightArr[rightIndex++] = arr[i];` `                ``freq.Add(freq[i]);` `            ``}` `        ``}`   `        ``// Recursively create Wavelet Trees for the left and` `        ``// right arrays` `        ``l = ``new` `WaveletTree(leftArr, low, mid);` `        ``r = ``new` `WaveletTree(rightArr, mid + 1, high);` `    ``}` `}`   `// Driver code` `class` `Program {` `    ``static` `void` `Main(``string``[] args)` `    ``{` `        ``int` `size = 5, high = ``int``.MinValue;` `        ``int``[] arr = { 1, 2, 3, 4, 5 };` `        ``for` `(``int` `i = 0; i < size; i++)` `            ``high = Math.Max(high, arr[i]);`   `        ``// Object of class wavelet tree` `        ``WaveletTree obj = ``new` `WaveletTree(arr, 1, high);` `    ``}` `}`

Output

` `

Height of the tree: O(log(max(A)) , where max(A) is the maximum element in the array A[].

Querying in Wavelet Trees

We have already constructed our wavelet tree for the given array. Now we will move on to our problem to calculate number of elements less than or equal to x in range [ L,R ] in the given array.
So, for each node we have a subsequence of original array, lowest and highest values present in the array and count of elements in left and right child.
Now,

```If high <= x,
we return R - L + 1.
i.e. all the elements in the current range is less than x.```

Otherwise, We will use variable LtCount = freq[ L-1 ] (i.e. elements going to left sub-tree from L-1) , RtCount = freq[ R ] (i.e. elements going to right sub-tree from R)
Now, we recursively call and add the return values of :

```left sub-tree with range[ LtCount + 1, RtCount ] and,
right sub-tree with range[ L - Ltcount,R - RtCount ]```

Below is the implementation in C++:

## CPP

 `// CPP program for querying in` `// wavelet tree Data Structure` `#include ` `using` `namespace` `std;` `#define N 100000`   `// Given Array` `int` `arr[N];`   `// wavelet tree class` `class` `wavelet_tree {` `public``:` `    ``// Range to elements` `    ``int` `low, high;`   `    ``// Left and Right child` `    ``wavelet_tree* l, *r;`   `    ``vector<``int``> freq;`   `    ``// Default constructor` `    ``// Array is in range [x, y]` `    ``// Indices are in range [from, to]` `    ``wavelet_tree(``int``* from, ``int``* to, ``int` `x, ``int` `y)` `    ``{` `        ``// Initialising low and high` `        ``low = x, high = y;`   `        ``// Array is of 0 length` `        ``if` `(from >= to)` `            ``return``;`   `        ``// Array is homogeneous` `        ``// Example : 1 1 1 1 1` `        ``if` `(high == low) {` `            ``// Assigning storage to freq array` `            ``freq.reserve(to - from + 1);`   `            ``// Initialising the Freq array` `            ``freq.push_back(0);`   `            ``// Assigning values` `            ``for` `(``auto` `it = from; it != to; it++) ` `            `  `                ``// freq will be increasing as there'll` `                ``// be no further sub-tree` `                ``freq.push_back(freq.back() + 1);` `            `  `            ``return``;` `        ``}`   `        ``// Computing mid` `        ``int` `mid = (low + high) / 2;`   `        ``// Lambda function to check if a number` `        ``// is less than or equal to mid` `        ``auto` `lessThanMid = [mid](``int` `x) {` `            ``return` `x <= mid;` `        ``};`   `        ``// Assigning storage to freq array` `        ``freq.reserve(to - from + 1);`   `        ``// Initialising the freq array` `        ``freq.push_back(0);`   `        ``// Assigning value to freq array` `        ``for` `(``auto` `it = from; it != to; it++) `   `            ``// If lessThanMid returns 1(true), we add` `            ``// 1 to previous entry. Otherwise, we add 0` `            ``// (element goes to right sub-tree)` `            ``freq.push_back(freq.back() + lessThanMid(*it));        `   `        ``// std::stable_partition partitions the array w.r.t Mid` `        ``auto` `pivot = stable_partition(from, to, lessThanMid);`   `        ``// Left sub-tree's object` `        ``l = ``new` `wavelet_tree(from, pivot, low, mid);`   `        ``// Right sub-tree's object` `        ``r = ``new` `wavelet_tree(pivot, to, mid + 1, high);` `    ``}`   `    ``// Count of numbers in range[L..R] less than ` `    ``// or equal to k` `    ``int` `kOrLess(``int` `l, ``int` `r, ``int` `k)` `    ``{` `        ``// No elements int range is less than k` `        ``if` `(l > r or k < low)` `            ``return` `0;`   `        ``// All elements in the range are less than k` `        ``if` `(high <= k)` `            ``return` `r - l + 1;`   `        ``// Computing LtCount and RtCount` `        ``int` `LtCount = freq[l - 1];` `        ``int` `RtCount = freq[r];`   `        ``// Answer is (no. of element <= k) in` `        ``// left + (those <= k) in right` `        ``return` `(``this``->l->kOrLess(LtCount + 1, RtCount, k) + ` `             ``this``->r->kOrLess(l - LtCount, r - RtCount, k));` `    ``}`   `};`   `// Driver code` `int` `main()` `{` `    ``int` `size = 5, high = INT_MIN;        ` `    ``int` `arr[] = {1, 2, 3, 4, 5};    ` `    `  `    ``// Array : 1 2 3 4 5` `    ``for` `(``int` `i = 0; i < size; i++)     ` `        ``high = max(high, arr[i]);`   `    ``// Object of class wavelet tree` `    ``wavelet_tree obj(arr, arr + size, 1, high);`   `    ``// count of elements less than 2 in range [1,3]` `    ``cout << obj.kOrLess(0, 3, 2) << ``'\n'``;`   `    ``return` `0;` `}`

## Python3

 `class` `WaveletTree:` `  ``# Constructor function` `    ``def` `__init__(``self``, from_idx, to_idx, low, high, arr):` `      ``# If the array is homogeneous, store the frequency and return` `        ``self``.low ``=` `low` `        ``self``.high ``=` `high` `        ``if` `from_idx >``=` `to_idx:` `            ``return` `        ``if` `self``.high ``=``=` `self``.low:` `            ``self``.freq ``=` `[``0``] ``*` `(to_idx ``-` `from_idx ``+` `2``)` `            ``for` `i ``in` `range``(from_idx, to_idx ``+` `1``):` `                ``self``.freq[i ``-` `from_idx ``+` `1``] ``=` `self``.freq[i ``-` `from_idx] ``+` `1` `            ``return` `        ``mid ``=` `(``self``.low ``+` `self``.high) ``/``/` `2` `         ``# Compute frequency array` `        ``self``.freq ``=` `[``0``] ``*` `(to_idx ``-` `from_idx ``+` `2``)` `        ``for` `i ``in` `range``(from_idx, to_idx ``+` `1``):` `            ``self``.freq[i ``-` `from_idx ``+` `1``] ``=` `self``.freq[i ``-` `from_idx] ``+` `(arr[i] <``=` `mid)` `        ``pivot ``=` `from_idx` `        ``while` `pivot <``=` `to_idx ``and` `arr[pivot] <``=` `mid:` `            ``pivot ``+``=` `1` `        ``self``.l ``=` `WaveletTree(from_idx, pivot ``-` `1``, ``self``.low, mid, arr)` `        ``self``.r ``=` `WaveletTree(pivot, to_idx, mid ``+` `1``, ``self``.high, arr)`   `    ``def` `kOrLess(``self``, l, r, k):` `        ``if` `l > r ``or` `k < ``self``.low:` `            ``return` `0` `        ``if` `self``.high <``=` `k:` `            ``return` `r ``-` `l ``+` `1` `        ``LtCount ``=` `self``.freq[l ``-` `1``]` `        ``RtCount ``=` `self``.freq[r]` `        ``return` `(` `            ``self``.l.kOrLess(LtCount ``+` `1``, RtCount, k) ``+` `            ``self``.r.kOrLess(l ``-` `LtCount, r ``-` `RtCount, k)` `        ``)`   `# Example usage` `size ``=` `5` `high ``=` `float``(``'-inf'``)`   `# Array : 1 2 3 4 5` `arr ``=` `[``1``, ``2``, ``3``, ``4``, ``5``]`   `for` `i ``in` `range``(size):` `    ``high ``=` `max``(high, arr[i])`   `# Object of class wavelet tree` `obj ``=` `WaveletTree(``0``, size ``-` `1``, ``1``, high, arr)`   `# count of elements less than 2 in range [1,3]` `print``(obj.kOrLess(``1``, ``3``, ``2``)) `

## Javascript

 `// Define a WaveletTree class with properties low, high, l, r, and freq` `// Default constructor` `// Array is in range [x, y]` `// Indices are in range [from, to]` `class WaveletTree {` `    ``constructor(from, to, x, y) {` `        ``this``.low = x;` `        ``this``.high = y;` `        ``if` `(from >= to) ``return``;` `        `  `        ``// Array is homogeneous` `        ``// Example : 1 1 1 1 1` `        ``if` `(``this``.high == ``this``.low) {` `            ``this``.freq = [0];` `            ``for` `(let it = from; it <= to; it++) ``this``.freq.push(``this``.freq[``this``.freq.length - 1] + 1);` `            ``return``;` `        ``}` `        ``let mid = Math.floor((``this``.low + ``this``.high) / 2);` `        `  `        ``// Lambda function to check if a number` `        ``// is less than or equal to mid` `        ``let lessThanMid = x => x <= mid;` `        ``this``.freq = [0];` `        ``for` `(let it = from; it <= to; it++) ``this``.freq.push(``this``.freq[``this``.freq.length - 1] + lessThanMid(arr[it]));` `        `  `        ``// std::stable_partition partitions the array w.r.t Mid` `        ``let pivot = from;` `        ``while` `(pivot <= to && lessThanMid(arr[pivot])) pivot++;` `        `  `        ``// Left sub-tree's object` `        ``this``.l = ``new` `WaveletTree(from, pivot - 1, ``this``.low, mid);` `        `  `        ``// Right sub-tree's object` `        ``this``.r = ``new` `WaveletTree(pivot, to, mid + 1, ``this``.high);` `    ``}`   `    ``// Count of numbers in range[L..R] less than ` `    ``// or equal to k` `    ``kOrLess(l, r, k) {` `        ``// No elements int range is less than k` `        ``if` `(l > r || k < ``this``.low) ``return` `0;` `        `  `        ``// All elements in the range are less than k` `        ``if` `(``this``.high <= k) ``return` `r - l + 1;` `        `  `        ``// Computing LtCount and RtCount` `        ``let LtCount = ``this``.freq[l - 1];` `        ``let RtCount = ``this``.freq[r];` `        `  `        ``// Answer is (no. of element <= k) in` `        ``// left + (those <= k) in right` `        ``return` `(` `            ``this``.l.kOrLess(LtCount + 1, RtCount, k) +` `            ``this``.r.kOrLess(l - LtCount, r - RtCount, k)` `        ``);` `    ``}` `}`   `// Example usage` `let size = 5,` `    ``high = Number.MIN_SAFE_INTEGER;` `    `  `// Array : 1 2 3 4 5` `let arr = [1, 2, 3, 4, 5];`   `for` `(let i = 0; i < size; i++) high = Math.max(high, arr[i]);`   `// Object of class wavelet tree` `let obj = ``new` `WaveletTree(0, size - 1, 1, high);`   `// count of elements less than 2 in range [1,3]` `console.log(obj.kOrLess(0 + 1 , 3 + 1 , 2));`

+

Output

`2`

Time Complexity: O(log(max(A)) , where max(A) is the maximum element in the array A[].
In this post we have discussed about a single problem on range queries without update. In further we will be discussing on range updates also.
References

Previous
Next