# Queries to evaluate the given equation in a range [L, R]

Given an array arr[] consisting of N integers and queries Q[][] of the form {L, R} where 0 ≤ L < R ≤ N – 1, the task for each query is to calculate the following equation :

KL | KL + 1 |…| KR – 1
where Ki = (arr[i] ^ arr[i+1]) | (arr[i] ~ arr[i+1])
“~” represents binary XNOR
“^” represents binary XOR
“|” represents binary OR

Examples:

Input: arr[] = {5, 2, 3, 0}, Q[][] = {{1, 3}, {0, 2}}
Output: 3 7
Explanation:
Query 1: L = 1, R = 3 : K1 = (2 ^ 3) | (2 ~ 3) = (3 | 2) = 3, K2 = (3 ^ 0) | (3 ~ 0) = (3 | 0) = 3.
Therefore, K1 | K2 = (3 | 3) = 3
Query 2: L = 0, R = 2 : K0 = 7, K1 = 3.
Therefore, K0 | K1 = (7 | 3) = 7
Input: arr[] = {4, 0, 1, 2}, Q[][] = {{1, 3}}
Output:

Naive Approach: The simplest approach to solve this problem is to traverse the indices [L, R – 1], and for each element, calculate Ki, where L ≤ i < R.

Time Complexity: O(N * sizeof(Q))

Efficient Approach: To optimize the above approach, the idea is to use a Segment Tree or Sparse Table. Follow the steps below to solve the problem:

• The following observation needs to be made:

XOR operation sets only those bits which are either set in arri or in arri+1
XNOR sets those bits which are either set in both ai and ai+1 or not set in both.

• Taking OR of both of these operations, all the bits up to the largest of the max(MSB(arri), MSB(arri+1)) will be set.
• Therefore, find the largest number, using Segment Tree, in between the given indices and set all of its bits to 1, to obtain the required answer.

Below is the implementation of the above approach:

## C++

 `// C++ Program to implement` `// the above approach` `#include ` `using` `namespace` `std;`   `// Function to obtain the` `// middle index of the range` `int` `getMid(``int` `s, ``int` `e)` `{` `    ``return` `s + (e - s) / 2;` `}`   `/* Recursive function to get the sum of ` `   ``values in the given range from 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 the segment of this node lies` `    ``// completely within the given range` `    ``if` `(l <= ss && r >= se)`   `        ``// Return maximum in the segment` `        ``return` `st[node];`   `    ``// If the segment of this node lies` `    ``// outside the given range` `    ``if` `(se < l || ss > r)` `        ``return` `-1;`   `    ``// If segment of this node lies` `    ``// partially in the 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));` `}`   `// Function to return the maximum in the` `// range from [l, r]` `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);` `}`   `// Function to construct Segment Tree` `// for the subarray [ss..se]` `int` `constructSTUtil(``int` `arr[], ``int` `ss, ``int` `se,` `                    ``int``* st, ``int` `si)` `{` `    ``// For a single element` `    ``if` `(ss == se) {` `        ``st[si] = arr[ss];` `        ``return` `arr[ss];` `    ``}`   `    ``// Otherwise` `    ``int` `mid = getMid(ss, se);`   `    ``// Recur for left subtree` `    ``st[si] = max(constructSTUtil(arr, ss, mid, st,` `                                 ``si * 2 + 1),`   `                 ``// Recur for right subtree` `                 ``constructSTUtil(arr, mid + 1, se,` `                                 ``st, si * 2 + 2));`   `    ``return` `st[si];` `}`   `// Function to construct Segment Tree from` `// the given array` `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` `    ``constructSTUtil(arr, 0, n - 1, st, 0);`   `    ``// Return the constructed Segment Tree` `    ``return` `st;` `}`   `// Driver Code` `int` `main()` `{` `    ``int` `arr[] = { 5, 2, 3, 0 };` `    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr);`   `    ``// Build the Segment Tree` `    ``// from the given array` `    ``int``* st = constructST(arr, n);`   `    ``vector > Q = { { 1, 3 }, { 0, 2 } };` `    ``for` `(``int` `i = 0; i < Q.size(); i++) {`   `        ``int` `max = getMax(st, n, Q[i], Q[i]);` `        ``int` `ok = 0;` `        ``for` `(``int` `i = 30; i >= 0; i--) {` `            ``if` `((max & (1 << i)) != 0)` `                ``ok = 1;`   `            ``if` `(!ok)` `                ``continue``;`   `            ``max |= (1 << i);` `        ``}`   `        ``cout << max << ``" "``;` `    ``}`   `    ``return` `0;` `}`

## Java

 `// Java Program to implement` `// the above approach` `import` `java.util.*;` `class` `GFG{`   `// Function to obtain the` `// middle index of the range` `static` `int` `getMid(``int` `s, ``int` `e)` `{` `    ``return` `s + (e - s) / ``2``;` `}`   `/* Recursive function to get the sum of ` `   ``values in the given range from 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 the segment of this node lies` `    ``// completely within the given range` `    ``if` `(l <= ss && r >= se)`   `        ``// Return maximum in the segment` `        ``return` `st[node];`   `    ``// If the segment of this node lies` `    ``// outside the given range` `    ``if` `(se < l || ss > r)` `        ``return` `-``1``;`   `    ``// If segment of this node lies` `    ``// partially in the 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``));` `}`   `// Function to return the maximum in the` `// range from [l, r]` `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"``);` `        ``return` `-``1``;` `    ``}`   `    ``return` `MaxUtil(st, ``0``, n - ``1``, l, r, ``0``);` `}`   `// Function to conSegment Tree` `// for the subarray [ss..se]` `static` `int` `constructSTUtil(``int` `arr[], ``int` `ss, ` `                           ``int` `se, ``int``[] st,` `                           ``int` `si)` `{` `    ``// For a single element` `    ``if` `(ss == se) ` `    ``{` `        ``st[si] = arr[ss];` `        ``return` `arr[ss];` `    ``}`   `    ``// Otherwise` `    ``int` `mid = getMid(ss, se);`   `    ``// Recur for left subtree` `    ``st[si] = Math.max(constructSTUtil(arr, ss, mid, st,` `                                            ``si * ``2` `+ ``1``),`   `                      ``// Recur for right subtree` `                      ``constructSTUtil(arr, mid + ``1``, se,` `                                       ``st, si * ``2` `+ ``2``));`   `    ``return` `st[si];` `}`   `// Function to conSegment Tree from` `// the given array` `static` `int``[] constructST(``int` `arr[], ``int` `n)` `{` `    ``// Height of Segment Tree` `    ``int` `x = (``int``)(Math.ceil(Math.log(n)));`   `    ``// 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` `    ``constructSTUtil(arr, ``0``, n - ``1``, st, ``0``);`   `    ``// Return the constructed Segment Tree` `    ``return` `st;` `}`   `// Driver Code` `public` `static` `void` `main(String[] args)` `{` `    ``int` `arr[] = { ``5``, ``2``, ``3``, ``0` `};` `    ``int` `n = arr.length;`   `    ``// Build the Segment Tree` `    ``// from the given array` `    ``int` `[]st = constructST(arr, n);`   `    ``int``[][] Q = { { ``1``, ``3` `}, { ``0``, ``2` `} };` `    ``for` `(``int` `i = ``0``; i < Q.length; i++) ` `    ``{` `        ``int` `max = getMax(st, n, Q[i][``0``], Q[i][``1``]);` `        ``int` `ok = ``0``;` `        ``for` `(``int` `j = ``30``; j >= ``0``; j--) ` `        ``{` `            ``if` `((max & (``1` `<< j)) != ``0``)` `                ``ok = ``1``;`   `            ``if` `(ok<=``0``)` `                ``continue``;`   `            ``max |= (``1` `<< j);` `        ``}` `        ``System.out.print(max+ ``" "``);` `    ``}` `}` `}`   `// This code is contributed by gauravrajput1`

## C#

 `// C# Program to implement` `// the above approach` `using` `System;` `class` `GFG {`   `    ``// Function to obtain the` `    ``// middle index of the range` `    ``static` `int` `getMid(``int` `s, ``int` `e)` `    ``{` `        ``return` `s + (e - s) / 2;` `    ``}`   `    ``/* Recursive function to get the sum of` `    ``values in the given range from the array.` `    ``The following are parameters for this` `    ``function:` `    ``st--> Pointer to segment tree` `    ``node--> Index of current node` `    ``in 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 the segment of this node lies` `        ``// completely within the given range` `        ``if` `(l <= ss && r >= se)`   `            ``// Return maximum in the segment` `            ``return` `st[node];`   `        ``// If the segment of this node lies` `        ``// outside the given range` `        ``if` `(se < l || ss > r)` `            ``return` `-1;`   `        ``// If segment of this node lies` `        ``// partially in the 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));` `    ``}`   `    ``// Function to return the maximum` `    ``// in the range from [l, r]` `    ``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"``);` `            ``return` `-1;` `        ``}` `        ``return` `MaxUtil(st, 0, n - 1, l, r, 0);` `    ``}`   `    ``// Function to conSegment Tree` `    ``// for the subarray [ss..se]` `    ``static` `int` `constructSTUtil(``int``[] arr, ``int` `ss, ``int` `se,` `                               ``int``[] st, ``int` `si)` `    ``{` `        ``// For a single element` `        ``if` `(ss == se) ` `        ``{` `            ``st[si] = arr[ss];` `            ``return` `arr[ss];` `        ``}`   `        ``// Otherwise` `        ``int` `mid = getMid(ss, se);`   `        ``// Recur for left subtree` `        ``st[si] = Math.Max(` `            ``constructSTUtil(arr, ss, mid, st, ` `                            ``si * 2 + 1),`   `            ``// Recur for right subtree` `            ``constructSTUtil(arr, mid + 1, se, st,` `                            ``si * 2 + 2));` `        ``return` `st[si];` `    ``}`   `    ``// Function to conSegment Tree` `    ``// from the given array` `    ``static` `int``[] constructST(``int``[] arr, ``int` `n)` `    ``{` `        ``// Height of Segment Tree` `        ``int` `x = (``int``)(Math.Ceiling(Math.Log(n)));`   `        ``// 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` `        ``constructSTUtil(arr, 0, n - 1, st, 0);`   `        ``// Return the constructed Segment Tree` `        ``return` `st;` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `Main(String[] args)` `    ``{` `        ``int``[] arr = {5, 2, 3, 0};` `        ``int` `n = arr.Length;`   `        ``// Build the Segment Tree` `        ``// from the given array` `        ``int``[] st = constructST(arr, n);`   `        ``int``[, ] Q = {{1, 3}, {0, 2}};` `        ``for` `(``int` `i = 0; i < Q.GetLength(0); i++) {` `            ``int` `max = getMax(st, n, Q[i, 0], Q[i, 1]);` `            ``int` `ok = 0;` `            ``for` `(``int` `j = 30; j >= 0; j--) {` `                ``if` `((max & (1 << j)) != 0)` `                    ``ok = 1;`   `                ``if` `(ok <= 0)` `                    ``continue``;`   `                ``max |= (1 << j);` `            ``}` `            ``Console.Write(max + ``" "``);` `        ``}` `    ``}` `}`   `// This code is contributed by Amit Katiyar`

Output:

```3 7

```

Time Complexity: O(N*log(sizeof(Q))
Auxiliary Space: O(N) My Personal Notes arrow_drop_up Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.