📜  所有子数组的XOR的XOR查询

📅  最后修改于: 2021-05-25 08:53:55             🧑  作者: Mango

给定一个由n个整数组成的数组A ,例如A 1 ,A 2 ,A 3 ,…,A n 。您将得到形式为[l,r]的Q个查询。任务是找到具有元素A l ,A l + 1 ,…..,A r的数组的所有子数组的XOR的XOR。
例子:

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

首先回想一下XOR的属性,
1. x⊕x = 0
2.如果x y = z,则x = y z
使用第一个属性,我们可以说对x进行任何X倍数的偶数运算将得出0,对x进行奇数倍运算将得出x。
如果要查找数组的所有子数组的XOR的XOPR,则需要找到在所有子数组中出现的奇数次的元素。
假设我们有一个数组[1、2、3]。它的子数组将是[1],[2],[3],[1、2],[2、3],[1、2、3]。
总共发生了1次,共1次。
2总共发生四次。
3次共发生3次。
我们可以观察到第i索引处的数字将具有(i + 1)x(sizeofarray – i)频率。
如果一个数组具有奇数个整数,则从第一个元素开始,每个备用元素在所有子数组中的总数将出现奇数次。因此,所有子阵列的XOR的XOR将是阵列中备用元素的XOR。
如果一个数组具有偶数个整数,则每个元素在所有子数组中的总数将出现偶数次。因此,所有子数组的XOR的XOR始终为0。
遍历每个查询的数组效率很低。通过使用递归与备用元素进行XOR运算,我们可以将XOR的值存储到每个元素
prefix_xor [i] = A [i]⊕prefix_xor [i – 2]
对于每个查询,我们的起始索引为l,结束索引为r。如果(r – 1 + 1)为奇数,答案将是prefix_xor [r]⊕prefix_xor [1-2]。
以下是此方法的实现:

C++
// CPP Program to answer queries on XOR of XORs
// of all subarray
#include 
#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) {
        query(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]);
 
    ansQueries(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


Javascript


输出:

0
2
6