GeeksforGeeks App
Open App
Browser
Continue

# C++ Program to 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[0]);` `    ``int` `q = 2;` `    ``int` `k[q] = { 4, 2 };` `    ``orsum(a, n, q, k);` `    ``return` `0;``}`

Output:

```238
230```

Time Complexity: O(N + Q*logN)

Auxiliary Space: O(4*MAX)

Please refer complete article on Find array sum using Bitwise OR after splitting given array in two halves after K circular shifts for more details!

My Personal Notes arrow_drop_up