C++查询所有子数组异或的异或

计算给定范围内所有子数组的异或并打印出来。例如

Input : arr[] = { 4, 1, 2, 3, 5 }, Q = 3

Queries

q1 = { 1, 2 }
q2 = { 2, 4 }
q3 = { 1, 4 }

Output : 0
2
0
Explanation : As the given problem states that we need to find XOR of all the subarrays present in the given range so as for query 2 the subarrays are :
{1}, {2}, {3}, {1, 2}, {2, 3}, (1, 2, 3}
So as you can see the number of occurrences of elements are :
1 is present 3 times
2 is present 4 times
3 is present 3 times
Now as we know the property of XOR is that the numbers that are present an even number of times get canceled out so out 2 got canceled out and just the XOR of 3 and 1 remained and that was our answer.

我们需要观察这个问题正在形成的模式,然后我们需要相应地实现它。

寻找解决方案的方法

在这个问题中,我们试图找到问题中存在的中间模式。什么时候。当我们看到该模式时,我们会相应地实施它并检查结果。

示例

上述方法的 C++ 代码

 
#include <bits/stdc++.h>
using namespace std;
void ansQueries(int prefeven[], int prefodd[], int l, int r){
    if ((r - l + 1) % 2 == 0) // 如果范围中存在的元素数是偶数
        cout << "0";
    else{
        if (l % 2 == 0) // 如果我是偶数
            cout << (prefeven[r] ^ prefeven[l - 1]) << "\n";
        else // 如果 l 是奇数
            cout << (prefodd[r] ^ prefodd[l - 1]) << "\n";
    }
}
int main(){
    int arr[] = {4, 1, 2, 3, 5};
    int n = sizeof(arr) / sizeof(int); // 我们数组的大小
    int l[] = {1, 2, 1}; // 给定查询的左索引
    int r[] = {2, 4, 4}; // 给定查询的正确索引
    int q = sizeof(l) / sizeof(int);         // 询问的次数
    int prefodd[n] = {0}, prefeven[n] = {0}; // 偶数和奇数索引的不同前缀异或
    for (int i = 1; i <= n; i++){
        if ((i) % 2 == 0){ // 如果我是偶那么我们改变 prefeven
            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];
        }
    }
    for (int i = 0; i < q; i++){
        ansQueries(prefeven, prefodd, l[i], r[i]);
    }
    return 0;
}
输出结果
02
0

以上代码说明

在这种方法中,我们首先观察到,如果我们的范围的大小是偶数,那么我们的答案将为零,因为当我们打印所有子数组时,每个数字都出现偶数次,因此通过对它们进行异或,我们下一部分的答案现在将是 0在这种情况下,范围的大小是奇数,出现奇数次的数字在给定范围内的偶数位置,我们的答案将只是出现在给定范围内偶数位置的数字的异或,我们保持两个前缀包含交替位置异或的数组,因为我们的 prefeven 包含所有偶数索引的异或,而 prefodd 包含所有奇数索引的异或,现在当我们解决查询时,我们只需要检查我们的 l 是偶数还是奇数,并相应地给出我们的答案.

结论

在本教程中,我们解决了一个问题来解决所有子数组异或的异或查询。我们还学习了针对此问题的 C++ 程序以及解决此问题的完整方法 (Normal)。我们可以用其他语言编写相同的程序,例如 C、java、python 和其他语言。我们希望本教程对您有所帮助。