Skip to content
Related Articles

Related Articles

Queries on XOR of greatest odd divisor of the range
  • Difficulty Level : Medium
  • Last Updated : 09 Jan, 2019

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++






#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;
}


Java




// 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


Python3




# 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


C#




// 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


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
Recommended Articles
Page :