给定一个由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