Open In App

Queries on XOR of XORs of all subarrays

Last Updated : 27 Jul, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array A of n integers, say A1, A2, A3, …, An. You are given Q queries of the form [l, r]. The task is to find the XOR of XORs of all the subarrays of an array having elements Al, Al+1, ….., Ar.

Examples: 

Input : A[] = { 1, 2, 3, 4, 5 }, Q = 3
        q1 = { 1, 2 }
        q2 = { 1, 3 }
        q3 = { 2, 4 }
Output : 0
         2
         6
For query 1, the extracted array is [1, 2] and 
subarrays of the array is [1], [2], [1, 2]. 
So, the answer is (1) ?  (2) ?  (1 ? 2) = 0.
For query 2, the extracted array is [1, 2, 3] and 
subarrays of the array is
[1], [2], [1, 2], [2, 3], [1, 2, 3]. 
So the answer is (1) ?  (2) ?  (3) ? (1 ?  2) ?  
                 (2 ?  3) ?  (1 ?  2 ?  3) = 2.
For query 3, the extracted array is [2, 3, 4] and 
subarrays of the array is 
[2], [3], [4], [2, 3], [3, 4], [2, 3, 4].
So the answer is (2) ? (3) ?  (4) ?  (2 ?  3) ?  
                 (3 ?  4) ?  (2 ?  3 ?  4) = 6.

Input : A[] = { 5, 8, 9, 1, 7 }, Q = 3
        query1 = { 1, 3 }
        query2 = { 3, 4 }
        query3 = { 2, 5 }
Output : 12
         0
         0

First of all recall the properties of XOR, 

  1. x ? x = 0 
  2. If x ? y = z, then x = y ? z 

Using the first property, we can say that any number x XORed even number of times will result in a 0 and odd number of times will result in x. 
If we want to find XOPR of XORs all the subarrays of an array, we need to find the elements which appear odd number of times in all subarrays in total.
Let’s say we have an array [1, 2, 3]. Its subarrays will be [1], [2], [3], [1, 2], [2, 3], [1, 2, 3]. 

  1. has occurred three times in total. 
  2. has occurred four times in total. 
  3. has occurred three times in total.

We can observe that number at ith index will have (i + 1)x(sizeofarray – i) frequency. 

If an array has odd number of integers, starting from the first element, every alternate element will appear odd number of times in all subarrays in total. Therefore, the XOR of XORs of all subarrays will be XOR of the alternate elements in the arrays. 

If an array has even number of integers, every element will appear even number of times in all subarrays in total. Therefore, the XOR of XORs of all subarrays will always be 0.
Traversing the array for every query is inefficient. We can store value of XORs upto every elements by XORing it with the alternate elements using recurrence 
prefix_xor[i] = A[i] ? prefix_xor[i – 2]

For every query, we have starting index as l and ending index as r. If (r – l + 1) odd, answer will be prefix_xor[r] ? prefix_xor[l – 2].

Below is the implementation of this approach:

C++




// CPP Program to answer queries on XOR of XORs
// of all subarray
#include <bits/stdc++.h>
#define N 100
using namespace std;
 
// Output for each query
void ansQueries(int prefeven[], int prefodd[],
                                 int l, int r)
{
    // If number of element is even.
    if ((r - l + 1) % 2 == 0)
        cout << "0";
 
    // If number of element is odd.
    else {
 
        // if l is even
        if (l % 2 == 0)
            cout << (prefeven[r] ^ prefeven[l - 1]);
 
        // if l is odd
        else
            cout << (prefodd[r] ^ prefodd[l - 1]);
    }
 
    cout << endl;
}
 
// Wrapper Function
void wrapper(int arr[], int n, int l[], int r[], int q)
{
    int prefodd[N] = { 0 }, prefeven[N] = { 0 };
 
    // Evaluating prefixodd and prefixeven
    for (int i = 1; i <= n; i++) {
        if ((i) % 2 == 0) {
            prefeven[i] = arr[i - 1] ^ prefeven[i - 1];
            prefodd[i] = prefodd[i - 1];
        }
        else {
            prefeven[i] = prefeven[i - 1];
            prefodd[i] = prefodd[i - 1] ^ arr[i - 1];
        }
    }
 
    int i = 0;
    while (i != q) {
        ansQueries(prefeven, prefodd, l[i], r[i]);
        i++;
    }
}
 
// Driven Program
int main()
{
    int arr[] = { 1, 2, 3, 4, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    int l[] = { 1, 1, 2 };
    int r[] = { 2, 3, 4 };
    int q = sizeof(l) / sizeof(l[0]);
 
    wrapper(arr, n, l, r, q);
    return 0;
}


Java




// JAVA Code for Queries on XOR
// of XORs of all subarrays
import java.util.*;
 
class GFG {
 
    // Output for each query
    static void ansQueries(int prefeven[],
                           int prefodd[],
                           int l, int r)
    {
        // If number of element is even.
        if ((r - l + 1) % 2 == 0)
            System.out.println("0");
                                                                                                                                                                                                                                                                                 
        // If number of element is odd.
        else
        {
            // if l is even
            if (l % 2 == 0)
                System.out.println(prefeven[r] ^
                                prefeven[l - 1]);
             
            // if l is odd
            else
                System.out.println(prefodd[r] ^
                                 prefodd[l - 1]);
        }
    }
     
    // Wrapper Function
    static void wrapper(int arr[], int n,
                        int l[], int r[],
                                   int q)
    {
        int prefodd[] = new int[100];
        int prefeven[] = new int[100];
         
        // Evaluating prefixodd
        // and prefixeven
        for (int i = 1; i <= n; i++) {
             
            if ((i) % 2 == 0) {
                 
                prefeven[i] = arr[i - 1] ^
                             prefeven[i - 1];
                 
                prefodd[i] = prefodd[i - 1];
            }
            else
            {
                prefeven[i] = prefeven[i - 1];
                prefodd[i] = prefodd[i - 1] ^
                             arr[i - 1];
            }
        }
         
        int i = 0;
         
        while (i != q){
             
            ansQueries(prefeven, prefodd,
                             l[i], r[i]);
            i++;
        }
    }
     
    /* Driver program to test above function */
    public static void main(String[] args)
    {
        int arr[] = {1, 2, 3, 4 , 5};
        int n = arr.length;
         
        int l[] = {1, 1, 2};
        int r[] = {2, 3, 4};
        int q = l.length;
         
        wrapper(arr, n, l, r, q);
    }
}
 
// This code is contributed by Arnav Kr. Mandal.


Python 3




# Python 3 Program to answer queries on
# XOR of XORs of all subarray
N = 100
 
# Output for each query
def ansQueries(prefeven, prefodd, l, r):
 
    # If number of element is even.
    if ((r - l + 1) % 2 == 0):
        print("0")
 
    # If number of element is odd.
    else :
 
        # if l is even
        if (l % 2 == 0):
            print(prefeven[r] ^
                  prefeven[l - 1])
 
        # if l is odd
        else:
            print(prefodd[r] ^
                  prefodd[l - 1])
 
# Wrapper Function
def wrapper(arr, n, l, r, q):
     
    prefodd = [0] * N
    prefeven = [0] * N
 
    # Evaluating prefixodd and prefixeven
    for i in range(1, n + 1) :
        if ((i) % 2 == 0) :
            prefeven[i] = arr[i - 1] ^ prefeven[i - 1]
            prefodd[i] = prefodd[i - 1]
         
        else :
            prefeven[i] = prefeven[i - 1]
            prefodd[i] = prefodd[i - 1] ^ arr[i - 1]
 
    i = 0
    while (i != q) :
        ansQueries(prefeven, prefodd, l[i], r[i])
        i += 1
 
# Driver Code
if __name__ == "__main__":
     
    arr = [ 1, 2, 3, 4, 5 ]
    n = len(arr)
 
    l = [ 1, 1, 2 ]
    r = [ 2, 3, 4 ]
    q = len(l)
 
    wrapper(arr, n, l, r, q)
 
# This code is contributed by ita_c


C#




// C# code for Queries on XOR
// of XORs of all subarrays
using System;
 
class GFG {
 
    // Output for each query
    static void ansQueries(int[] prefeven,
                           int[] prefodd,
                           int l, int r)
    {
        // If number of element is even.
        if ((r - l + 1) % 2 == 0)
            Console.WriteLine("0");
 
        // If number of element is odd.
        else {
            // if l is even
            if (l % 2 == 0)
                Console.WriteLine(prefeven[r] ^ prefeven[l - 1]);
 
            // if l is odd
            else
                Console.WriteLine(prefodd[r] ^ prefodd[l - 1]);
        }
    }
 
    // Wrapper Function
    static void wrapper(int[] arr, int n,
                        int[] l, int[] r,
                        int q)
    {
        int[] prefodd = new int[100];
        int[] prefeven = new int[100];
 
        // Evaluating prefixodd
        // and prefixeven
        for (int i = 1; i <= n; i++) {
 
            if ((i) % 2 == 0) {
 
                prefeven[i] = arr[i - 1] ^ prefeven[i - 1];
 
                prefodd[i] = prefodd[i - 1];
            }
            else {
                prefeven[i] = prefeven[i - 1];
                prefodd[i] = prefodd[i - 1] ^ arr[i - 1];
            }
        }
 
        int j = 0;
 
        while (j != q) {
 
            ansQueries(prefeven, prefodd,
                    l[j], r[j]);
            j++;
        }
    }
 
    /* Driver program to test above function */
    public static void Main()
    {
        int[] arr = { 1, 2, 3, 4, 5 };
        int n = arr.Length;
 
        int[] l = { 1, 1, 2 };
        int[] r = { 2, 3, 4 };
        int q = l.Length;
 
        wrapper(arr, n, l, r, q);
    }
}
 
// This code is contributed by vt_m.


PHP




<?php
// php Program to answer
// queries on XOR of XORs
// of all subarray
// Output for each query
 
function ansQueries($prefeven, $prefodd,
                                $l, $r)
{
     
    // If number of element is even.
    if (($r - $l + 1) % 2 == 0)
    {
        echo "0";
}
 
    // If number of element is odd.
    else {
 
        // if l is even
        if ($l % 2 == 0)
            echo ($prefeven[$r] ^
                  $prefeven[$l - 1]);
 
        // if l is odd
        else
            echo ($prefodd[$r] ^
                  $prefodd[$l - 1]);
    }
 
    echo "\n";
}
 
// Wrapper Function
function wrapper(array $arr, $n, array $l,
                            array $r, $q)
{
    $prefodd=array_fill(0,100,0);
    $prefeven=array_fill(0,100,0);
 
    // Evaluating prefixodd
    // and prefixeven
    for ($i = 1; $i <= $n; $i++)
    {
        if (($i) % 2 == 0)
        {
            $prefeven[$i] = $arr[$i - 1] ^
                        $prefeven[$i - 1];
            $prefodd[$i] = $prefodd[$i - 1];
        }
        else {
            $prefeven[$i] = $prefeven[$i - 1];
            $prefodd[$i] = $prefodd[$i - 1] ^
                                $arr[$i - 1];
        }
    }
 
    $i = 0;
    while ($i != $q) {
        ansQueries($prefeven, $prefodd,
                    $l[$i], $r[$i]);
        $i++;
    }
}
 
    // Driver code
    $arr = array ( 1, 2, 3, 4, 5 );
    $n = sizeof($arr) / sizeof($arr[0]);
 
    $l=array ( 1, 1, 2 );
    $r=array ( 2, 3, 4 );
    $q = sizeof($l) / sizeof($l[0]);
 
    wrapper($arr, $n, $l, $r, $q);
 
// This code is contributed by mits
?>


Javascript




<script>
 
// JavaScript program for Queries on XOR
// of XORs of all subarrays
 
// Output for each query
    function ansQueries(prefeven,
                           prefodd,
                           l, r)
    {
        // If number of element is even.
        if ((r - l + 1) % 2 == 0)
            document.write("0");
                                                                                                                                                                                                                                                                                   
        // If number of element is odd.
        else
        {
            // if l is even
            if (l % 2 == 0)
                document.write(prefeven[r] ^
                                prefeven[l - 1]) ;
               
            // if l is odd
            else
                document.write(prefodd[r] ^
                                 prefodd[l - 1] );
        }
        document.write( "<br/>");
    }
       
    // Wrapper Function
    function wrapper(arr, n,
                        l, r, q)
    {
        let prefodd = [];
        let prefeven = [];
           
        // Evaluating prefixodd
        // and prefixeven
        for (let i = 1; i <= n; i++) {
               
            if ((i) % 2 == 0) {
                   
                prefeven[i] = arr[i - 1] ^
                             prefeven[i - 1];
                   
                prefodd[i] = prefodd[i - 1];
            }
            else
            {
                prefeven[i] = prefeven[i - 1];
                prefodd[i] = prefodd[i - 1] ^
                             arr[i - 1];
            }
        }
           
        let i = 0;
           
        while (i != q){
               
            ansQueries(prefeven, prefodd,
                             l[i], r[i]);
            i++;
        }
    }
 
 
// Driver code
 
        let arr = [1, 2, 3, 4 , 5];
        let n = arr.length;
           
        let l = [1, 1, 2];
        let r = [2, 3, 4];
        let q = l.length;
           
        wrapper(arr, n, l, r, q);
                             
</script>


Output

0
2
6

Time Complexity: O(n)
Auxiliary Space: O(n)



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

Similar Reads