Open In App

Javascript Program to Find array sum using Bitwise OR after splitting given array in two halves after K circular shifts

Last Updated : 31 Mar, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

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:
 

Javascript




<script>
// javascript program to find Bitwise OR of two
// equal halves of an array after performing
// K right circular shifts
    const MAX = 100005;
 
    // Array for storing
    // the segment tree
    var seg = Array(4 * MAX).fill(0);
 
    // Function to build the segment tree
    function build(node , l , r , a) {
        if (l == r)
            seg[node] = a[l];
 
        else {
            var mid = parseInt((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]
    function query(node , l , r , start , end , 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
        var mid = parseInt((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
    function orsum(a , n , q , k) {
 
        // Function to build the segment Tree
        build(1, 0, n - 1, a);
 
        // Loop to handle q queries
        for (j = 0; j < q; j++) {
 
            // Effective number of
            // right circular shifts
            var 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]
            var 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]
            var first = (query(1, 0, n - 1, 0, n / 2 - 1 - i, a) | query(1, 0, n - 1, n - i, n - 1, a));
 
            var temp = sec + first;
 
            // Print final answer to the query
            document.write(temp + "<br/>");
        }
    }
 
    // Driver Code
        var a = [ 7, 44, 19, 86, 65, 39, 75, 101 ];
        var n = a.length;
        var q = 2;
 
        var k = [ 4, 2 ];
 
        orsum(a, n, q, k);
 
// This code is contributed by Rajput-Ji.
</script>


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!



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads