GeeksforGeeks App
Open App
Browser
Continue

# Python3 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:

## 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`

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