Queries on XOR of greatest odd divisor of the range

Given an array of N positive integers. There are Q queries, each include a range [L, R]. For each query output the xor of greatest odd divisor of each number in that range.

Examples:

Input : arr[] = { 3, 4, 5 }
query 1: [0, 2]
query 2: [1, 2]
Output : 7 4
Greatest odd divisor are: { 3, 1, 5 }
XOR of 3, 1, 5 is 7
XOR of 1, 5 is 4

Input : arr[] = { 2, 1, 2 }
query 1: [0, 2]
Output : 1

The idea is to precompute the greatest odd divisor of the array and store it in an array, say preXOR[]. Now, precompute and store prefix XOR of the array preXOR[]. To answer each query, return (preXOR[r] xor preXOR[l-1]).

Below is the implementatin of this approach:

C++



filter_none

edit
close

play_arrow

link
brightness_4
code

#include <bits/stdc++.h>
using namespace std;
  
// Precompute the prefix XOR of greatest 
// odd divisor
void prefixXOR(int arr[], int preXOR[], int n)
{
    // Finding the Greatest Odd divisor
    for (int i = 0; i < n; i++) {
        while (arr[i] % 2 != 1)
            arr[i] /= 2;
  
        preXOR[i] = arr[i];
    }
  
    // Finding prefix XOR
    for (int i = 1; i < n; i++)
        preXOR[i] = preXOR[i - 1] ^ preXOR[i];
}
  
// Return XOR of the range
int query(int preXOR[], int l, int r)
{
    if (l == 0)
        return preXOR[r];
    else
        return preXOR[r] ^ preXOR[l - 1];
}
  
// Driven Program
int main()
{
    int arr[] = { 3, 4, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    int preXOR[n];
    prefixXOR(arr, preXOR, n);
  
    cout << query(preXOR, 0, 2) << endl;
    cout << query(preXOR, 1, 2) << endl;
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java code Queries on XOR of 
// greatest odd divisor of the range
import java.io.*;
  
class GFG 
{
    // Precompute the prefix XOR of greatest 
    // odd divisor
    static void prefixXOR(int arr[], int preXOR[], int n)
    {
        // Finding the Greatest Odd divisor
        for (int i = 0; i < n; i++) 
        {
            while (arr[i] % 2 != 1)
                arr[i] /= 2;
      
            preXOR[i] = arr[i];
        }
      
        // Finding prefix XOR
        for (int i = 1; i < n; i++)
            preXOR[i] = preXOR[i - 1] ^ preXOR[i];
    }
      
    // Return XOR of the range
    static int query(int preXOR[], int l, int r)
    {
        if (l == 0)
            return preXOR[r];
        else
            return preXOR[r] ^ preXOR[l - 1];
    }
      
    // Driven Program
    public static void main (String[] args) 
    {
        int arr[] = { 3, 4, 5 };
        int n = arr.length;
      
        int preXOR[] = new int[n];
        prefixXOR(arr, preXOR, n);
      
        System.out.println(query(preXOR, 0, 2)) ;
        System.out.println (query(preXOR, 1, 2));
      
              
    }
}
  
// This article is contributed by vt_m

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Precompute the prefix XOR of greatest 
# odd divisor
def prefixXOR(arr, preXOR, n):
      
    # Finding the Greatest Odd divisor
    for i in range(0, n, 1):
        while (arr[i] % 2 != 1):
            arr[i] = int(arr[i] / 2
  
        preXOR[i] = arr[i]
  
    # Finding prefix XOR
    for i in range(1, n, 1):
        preXOR[i] = preXOR[i - 1] ^ preXOR[i]
  
# Return XOR of the range
def query(preXOR, l, r):
    if (l == 0):
        return preXOR[r]
    else:
        return preXOR[r] ^ preXOR[l - 1]
  
# Driver Code
if __name__ == '__main__':
    arr = [3, 4, 5]
    n = len(arr)
  
    preXOR = [0 for i in range(n)]
    prefixXOR(arr, preXOR, n)
  
    print(query(preXOR, 0, 2))
    print(query(preXOR, 1, 2))
      
# This code is contributed by
# Sahil_shelangia

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# code Queries on XOR of 
// greatest odd divisor of the range
using System;
  
class GFG 
{
    // Precompute the prefix XOR of greatest 
    // odd divisor
    static void prefixXOR(int []arr, 
                    int []preXOR, int n)
    {
        // Finding the Greatest Odd divisor
        for (int i = 0; i < n; i++) 
        {
            while (arr[i] % 2 != 1)
                arr[i] /= 2;
      
            preXOR[i] = arr[i];
        }
      
        // Finding prefix XOR
        for (int i = 1; i < n; i++)
            preXOR[i] = preXOR[i - 1] ^ preXOR[i];
    }
      
    // Return XOR of the range
    static int query(int [] preXOR, int l, int r)
    {
        if (l == 0)
            return preXOR[r];
        else
            return preXOR[r] ^ preXOR[l - 1];
    }
      
    // Driven Program
    public static void Main () 
    {
        int []arr = { 3, 4, 5 };
        int n = arr.Length;
      
        int []preXOR = new int[n];
        prefixXOR(arr, preXOR, n);
      
        Console.WriteLine(query(preXOR, 0, 2)) ;
        Console.WriteLine (query(preXOR, 1, 2));
    }
}
  
// This code is contributed by vt_m

chevron_right


Output:

7
4

This article is contributed by Anuj Chauhan. 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 write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Improved By : sahilshelangia

Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.