 GFG App
Open App Browser
Continue

# Find array sum using Bitwise OR after splitting given array in two halves after K circular shifts

Given an array A[] of length N, where N is an even number, the task is to answer Q independent queries where each query consists of a positive integer K representing the number of circular shifts performed on the array and find the sum of elements by performing Bitwise OR operation on the divided array.
Note: Each query begins with the original array.
Examples:

Input: A[] = {12, 23, 4, 21, 22, 76}, Q = 1, K = 2
Output: 117
Explanation:
Since K is 2, modified array A[]={22, 76, 12, 23, 4, 21}.
Bitwise OR of first half of array = (22 | 76 | 12) = 94
Bitwise OR of second half of array = (21 | 23 | 4) = 23
Sum of OR values is 94 + 23 = 117
Input: A[] = {7, 44, 19, 86, 65, 39, 75, 101}, Q = 1, K = 4
Output: 238
Since K is 4, modified array A[]={65, 39, 75, 101, 7, 44, 19, 86}.
Bitwise OR of first half of array = 111
Bitwise OR of second half of array = 127
Sum of OR values is 111 + 127 = 238

Naive Approach:
To solve the problem mentioned above the simplest approach is to shift each element of the array by K % (N / 2) and then traverse the array to calculate the OR of the two halves for every query. But this method is not efficient and hence can be optimized further.
Efficient Approach:
To optimize the above mentioned approach we can take the help of Segment Tree data structure.

Observation:

• We can observe that after exactly N / 2 right circular shifts the two halves of the array become the same as in the original array. This effectively reduces the number of rotations to K % (N / 2).
• Performing a right circular shift is basically shifting the last element of the array to the front. So for any positive integer X performing X right circular shifts is equal to shifting the last X elements of the array to the front.

Following are the steps to solve the problem :

• Construct a segment tree for the original array A[] and assign a variable let’s say i = K % (N / 2).
• Then for each query we use the segment tree of find the bitwise OR; that is Bitwise OR of i elements from the end OR bitwise OR of the first (N / 2) – i – 1 elements.
• Then calculate the bitwise OR of elements in range [(N / 2) – i, N – i – 1].
• Add the two results to get the answer for the ith query.
Below is the implementation of the above approach:

## C++

 `// C++ Program to find Bitwise OR of two` `// equal halves of an array after performing` `// K right circular shifts` `#include ` `const` `int` `MAX = 100005;` `using` `namespace` `std;`   `// Array for storing` `// the segment tree` `int` `seg[4 * MAX];`   `// Function to build the segment tree` `void` `build(``int` `node, ``int` `l, ``int` `r, ``int` `a[])` `{` `    ``if` `(l == r)` `        ``seg[node] = a[l];`   `    ``else` `{` `        ``int` `mid = (l + r) / 2;`   `        ``build(2 * node, l, mid, a);` `        ``build(2 * node + 1, mid + 1, r, a);`   `        ``seg[node] = (seg[2 * node]` `                     ``| seg[2 * node + 1]);` `    ``}` `}`   `// Function to return the OR` `// of elements in the range [l, r]` `int` `query(``int` `node, ``int` `l, ``int` `r,` `          ``int` `start, ``int` `end, ``int` `a[])` `{` `    ``// Check for out of bound condition` `    ``if` `(l > end or r < start)` `        ``return` `0;`   `    ``if` `(start <= l and r <= end)` `        ``return` `seg[node];`   `    ``// Find middle of the range` `    ``int` `mid = (l + r) / 2;`   `    ``// Recurse for all the elements in array` `    ``return` `((query(2 * node, l, mid,` `                   ``start, end, a))` `            ``| (query(2 * node + 1, mid + 1,` `                     ``r, start, end, a)));` `}`   `// Function to find the OR sum` `void` `orsum(``int` `a[], ``int` `n, ``int` `q, ``int` `k[])` `{` `    ``// Function to build the segment Tree` `    ``build(1, 0, n - 1, a);`   `    ``// Loop to handle q queries` `    ``for` `(``int` `j = 0; j < q; j++) {` `        ``// Effective number of` `        ``// right circular shifts` `        ``int` `i = k[j] % (n / 2);`   `        ``// Calculating the OR of` `        ``// the two halves of the` `        ``// array from the segment tree`   `        ``// OR of second half of the` `        ``// array [n/2-i, n-1-i]` `        ``int` `sec = query(1, 0, n - 1,` `                        ``n / 2 - i, n - i - 1, a);`   `        ``// OR of first half of the array` `        ``// [n-i, n-1]OR[0, n/2-1-i]` `        ``int` `first = (query(1, 0, n - 1, 0,` `                           ``n / 2 - 1 - i, a)` `                     ``| query(1, 0, n - 1,` `                             ``n - i, n - 1, a));`   `        ``int` `temp = sec + first;`   `        ``// Print final answer to the query` `        ``cout << temp << endl;` `    ``}` `}`   `// Driver Code` `int` `main()` `{`   `    ``int` `a[] = { 7, 44, 19, 86, 65, 39, 75, 101 };` `    ``int` `n = ``sizeof``(a) / ``sizeof``(a);`   `    ``int` `q = 2;`   `    ``int` `k[q] = { 4, 2 };`   `    ``orsum(a, n, q, k);`   `    ``return` `0;` `}`

## Java

 `// Java program to find Bitwise OR of two` `// equal halves of an array after performing` `// K right circular shifts` `import` `java.util.*;`   `class` `GFG{` `    `  `static` `int` `MAX = ``100005``; `   `// Array for storing` `// the segment tree` `static` `int` `[]seg = ``new` `int``[``4` `* MAX];`   `// Function to build the segment tree` `static` `void` `build(``int` `node, ``int` `l, ` `                  ``int` `r, ``int` `a[])` `{` `    ``if` `(l == r)` `        ``seg[node] = a[l];`   `    ``else` `    ``{` `        ``int` `mid = (l + r) / ``2``;`   `        ``build(``2` `* node, l, mid, a);` `        ``build(``2` `* node + ``1``, mid + ``1``, r, a);`   `        ``seg[node] = (seg[``2` `* node] | ` `                     ``seg[``2` `* node + ``1``]);` `    ``}` `}`   `// Function to return the OR` `// of elements in the range [l, r]` `static` `int` `query(``int` `node, ``int` `l, ``int` `r,` `                 ``int` `start, ``int` `end, ``int` `a[])` `{` `    `  `    ``// Check for out of bound condition` `    ``if` `(l > end || r < start)` `        ``return` `0``;`   `    ``if` `(start <= l && r <= end)` `        ``return` `seg[node];`   `    ``// Find middle of the range` `    ``int` `mid = (l + r) / ``2``;`   `    ``// Recurse for all the elements in array` `    ``return` `((query(``2` `* node, l, mid,` `                   ``start, end, a)) |` `            ``(query(``2` `* node + ``1``, mid + ``1``,` `                   ``r, start, end, a)));` `}`   `// Function to find the OR sum` `static` `void` `orsum(``int` `a[], ``int` `n, ` `                  ``int` `q, ``int` `k[])` `{` `    `  `    ``// Function to build the segment Tree` `    ``build(``1``, ``0``, n - ``1``, a);`   `    ``// Loop to handle q queries` `    ``for``(``int` `j = ``0``; j < q; j++)` `    ``{` `        `  `        ``// Effective number of` `        ``// right circular shifts` `        ``int` `i = k[j] % (n / ``2``);`   `        ``// Calculating the OR of` `        ``// the two halves of the` `        ``// array from the segment tree`   `        ``// OR of second half of the` `        ``// array [n/2-i, n-1-i]` `        ``int` `sec = query(``1``, ``0``, n - ``1``,` `                        ``n / ``2` `- i, ` `                        ``n - i - ``1``, a);`   `        ``// OR of first half of the array` `        ``// [n-i, n-1]OR[0, n/2-1-i]` `        ``int` `first = (query(``1``, ``0``, n - ``1``, ``0``,` `                           ``n / ``2` `- ``1` `- i, a) |` `                     ``query(``1``, ``0``, n - ``1``,` `                           ``n - i, n - ``1``, a));`   `        ``int` `temp = sec + first;`   `        ``// Print final answer to the query` `        ``System.out.print(temp + ``"\n"``);` `    ``}` `}`   `// Driver Code` `public` `static` `void` `main(String[] args)` `{`   `    ``int` `a[] = { ``7``, ``44``, ``19``, ``86``, ``65``, ``39``, ``75``, ``101` `};` `    ``int` `n = a.length;` `    ``int` `q = ``2``;`   `    ``int` `k[] = { ``4``, ``2` `};`   `    ``orsum(a, n, q, k);` `}` `}`   `// This code is contributed by 29AjayKumar`

## Python3

 `# Python3 program to find Bitwise OR of two` `# equal halves of an array after performing` `# K right circular shifts` `MAX` `=` `100005`   `# Array for storing` `# the segment tree` `seg ``=` `[``0``] ``*` `(``4` `*` `MAX``)`   `# Function to build the segment tree` `def` `build(node, l, r, a):`   `    ``if` `(l ``=``=` `r):` `        ``seg[node] ``=` `a[l]`   `    ``else``:` `        ``mid ``=` `(l ``+` `r) ``/``/` `2`   `        ``build(``2` `*` `node, l, mid, a)` `        ``build(``2` `*` `node ``+` `1``, mid ``+` `1``, r, a)` `        `  `        ``seg[node] ``=` `(seg[``2` `*` `node] | ` `                     ``seg[``2` `*` `node ``+` `1``])`   `# Function to return the OR` `# of elements in the range [l, r]` `def` `query(node, l, r, start, end, a):` `    `  `    ``# Check for out of bound condition` `    ``if` `(l > end ``or` `r < start):` `        ``return` `0`   `    ``if` `(start <``=` `l ``and` `r <``=` `end):` `        ``return` `seg[node]`   `    ``# Find middle of the range` `    ``mid ``=` `(l ``+` `r) ``/``/` `2`   `    ``# Recurse for all the elements in array` `    ``return` `((query(``2` `*` `node, l, mid, ` `                       ``start, end, a)) | ` `            ``(query(``2` `*` `node ``+` `1``, mid ``+` `1``, ` `                       ``r, start, end, a)))`   `# Function to find the OR sum` `def` `orsum(a, n, q, k):`   `    ``# Function to build the segment Tree` `    ``build(``1``, ``0``, n ``-` `1``, a)`   `    ``# Loop to handle q queries` `    ``for` `j ``in` `range``(q):` `        `  `        ``# Effective number of` `        ``# right circular shifts` `        ``i ``=` `k[j] ``%` `(n ``/``/` `2``)`   `        ``# Calculating the OR of` `        ``# the two halves of the` `        ``# array from the segment tree`   `        ``# OR of second half of the` `        ``# array [n/2-i, n-1-i]` `        ``sec ``=` `query(``1``, ``0``, n ``-` `1``, n ``/``/` `2` `-` `i,` `                          ``n ``-` `i ``-` `1``, a)`   `        ``# OR of first half of the array` `        ``# [n-i, n-1]OR[0, n/2-1-i]` `        ``first ``=` `(query(``1``, ``0``, n ``-` `1``, ``0``, ` `                             ``n ``/``/` `2` `-` `                             ``1` `-` `i, a) |` `                 ``query(``1``, ``0``, n ``-` `1``, ` `                             ``n ``-` `i, ` `                             ``n ``-` `1``, a))`   `        ``temp ``=` `sec ``+` `first`   `        ``# Print final answer to the query` `        ``print``(temp)`   `# Driver Code` `if` `__name__ ``=``=` `"__main__"``:`   `    ``a ``=` `[ ``7``, ``44``, ``19``, ``86``, ``65``, ``39``, ``75``, ``101` `]` `    ``n ``=` `len``(a)` `    `  `    ``q ``=` `2` `    ``k ``=` `[ ``4``, ``2` `]` `    `  `    ``orsum(a, n, q, k)`   `# This code is contributed by chitranayal `

## C#

 `// C# program to find Bitwise OR of two ` `// equal halves of an array after performing ` `// K right circular shifts ` `using` `System;` `class` `GFG{ ` `    `  `static` `int` `MAX = 100005; `   `// Array for storing ` `// the segment tree ` `static` `int` `[]seg = ``new` `int``[4 * MAX]; `   `// Function to build the segment tree ` `static` `void` `build(``int` `node, ``int` `l, ` `                  ``int` `r, ``int` `[]a) ` `{ ` `    ``if` `(l == r) ` `        ``seg[node] = a[l]; `   `    ``else` `    ``{ ` `        ``int` `mid = (l + r) / 2; `   `        ``build(2 * node, l, mid, a); ` `        ``build(2 * node + 1, mid + 1, r, a); `   `        ``seg[node] = (seg[2 * node] | ` `                     ``seg[2 * node + 1]); ` `    ``} ` `} `   `// Function to return the OR ` `// of elements in the range [l, r] ` `static` `int` `query(``int` `node, ``int` `l, ``int` `r, ` `                 ``int` `start, ``int` `end, ``int` `[]a) ` `{ ` `    `  `    ``// Check for out of bound condition ` `    ``if` `(l > end || r < start) ` `        ``return` `0; `   `    ``if` `(start <= l && r <= end) ` `        ``return` `seg[node]; `   `    ``// Find middle of the range ` `    ``int` `mid = (l + r) / 2; `   `    ``// Recurse for all the elements in array ` `    ``return` `((query(2 * node, l, mid, ` `                      ``start, end, a)) | ` `            ``(query(2 * node + 1, mid + 1, ` `                   ``r, start, end, a))); ` `} `   `// Function to find the OR sum ` `static` `void` `orsum(``int` `[]a, ``int` `n, ` `                  ``int` `q, ``int` `[]k) ` `{ ` `    `  `    ``// Function to build the segment Tree ` `    ``build(1, 0, n - 1, a); `   `    ``// Loop to handle q queries ` `    ``for``(``int` `j = 0; j < q; j++) ` `    ``{ ` `        `  `        ``// Effective number of ` `        ``// right circular shifts ` `        ``int` `i = k[j] % (n / 2); `   `        ``// Calculating the OR of ` `        ``// the two halves of the ` `        ``// array from the segment tree `   `        ``// OR of second half of the ` `        ``// array [n/2-i, n-1-i] ` `        ``int` `sec = query(1, 0, n - 1, ` `                        ``n / 2 - i, ` `                        ``n - i - 1, a); `   `        ``// OR of first half of the array ` `        ``// [n-i, n-1]OR[0, n/2-1-i] ` `        ``int` `first = (query(1, 0, n - 1, 0, ` `                         ``n / 2 - 1 - i, a) | ` `                    ``query(1, 0, n - 1, ` `                          ``n - i, n - 1, a)); `   `        ``int` `temp = sec + first; `   `        ``// Print readonly answer to the query ` `        ``Console.Write(temp + ``"\n"``); ` `    ``} ` `} `   `// Driver Code ` `public` `static` `void` `Main(String[] args) ` `{ ` `    ``int` `[]a = { 7, 44, 19, 86, 65, 39, 75, 101 }; ` `    ``int` `n = a.Length; ` `    ``int` `q = 2; `   `    ``int` `[]k = { 4, 2 }; `   `    ``orsum(a, n, q, k); ` `} ` `} `   `// This code is contributed by 29AjayKumar`

## Javascript

 ``

Output:

```238
230```

Time Complexity: O(N + Q*log(N))

Auxiliary Space: O(4*MAX)

My Personal Notes arrow_drop_up