给定大小为N (N为4的倍数)的XOR查询的数组q [] ,该数组描述相同大小的数组,如下所示:
q[0 – 3] describe arr[0 – 3], q[4 – 7] describe arr[4 – 7], and so on…
If arr[0 – 3] = {a1, a2, a3, a4} then
q[0 – 3] = {a1 ⊕ a2 ⊕ a3, a1 ⊕ a2 ⊕ a4, a1 ⊕ a3 ⊕ a4, a2 ⊕ a3 ⊕ a4}
当仅给出q []时,任务是查找原始数组arr []的值。
例子:
Input: q[] = {4, 1, 7, 0}
Output: 2 5 3 6
a1 ⊕ a2 ⊕ a3 = 4 ⊕ 1 ⊕ 7 = 2
a1 ⊕ a2 ⊕ a4 = 4 ⊕ 1 ⊕ 0 = 5
a1 ⊕ a3 ⊕ a4 = 4 ⊕ 7 ⊕ 0 = 3
a2 ⊕ a3 ⊕ a4 = 1 ⊕ 7 ⊕ 0 = 6
Input: q[] = {4, 1, 7, 0, 8, 5, 1, 4}
Output: 2 5 3 6 12 9 13 0
方法:从xor的性质来看, a⊕a = 0和a⊕0 = a 。
(a⊕b)c)⊕(b⊕c⊕d)= a⊕d (As(b⊕c)⊕(b⊕c)= 0)
因此,我们将数组分为4个元素的组,对于每个组(a,b,c,d),我们将
得到以下查询的结果:
- a⊕b⊕c
- a⊕b⊕d
- a⊕c⊕d
- b⊕c⊕d
As (a ⊕ b ⊕ c) ⊕ (b ⊕ c ⊕ d) = a ⊕ d,
using this (a ⊕ d) we can get b and c from query 2 and 3 in the following manner:
(a ⊕ b ⊕ d) ⊕ (a ⊕ d) = b
(a ⊕ c ⊕ d) ⊕ (a ⊕ d) = c
Then using b and c we can get a from query 1 and d from query 4 in the following way:
(a ⊕ b ⊕ c) ⊕ (b) ⊕ (c) = a
(b ⊕ c ⊕ d) ⊕ (b) ⊕ (c) = d
This process will be repeated (iteratively) for all groups of 4 elements and we will get elements of all indices(ex.(a, a, a, a) then (a, a, a, a) etc.)
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Utility function to print the contents of the array
void printArray(int arr[], int n)
{
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
}
// Function to find the required array
void findArray(int q[], int n)
{
int arr[n], ans;
for (int k = 0, j = 0; j < n / 4; j++) {
ans = q[k] ^ q[k + 3];
arr[k + 1] = q[k + 1] ^ ans;
arr[k + 2] = q[k + 2] ^ ans;
arr[k] = q[k] ^ ((arr[k + 1]) ^ (arr[k + 2]));
arr[k + 3] = q[k + 3] ^ (arr[k + 1] ^ arr[k + 2]);
k += 4;
}
// Print the array
printArray(arr, n);
}
// Driver code
int main()
{
int q[] = { 4, 1, 7, 0 };
int n = sizeof(q) / sizeof(q[0]);
findArray(q, n);
return 0;
}
Java
// Java implementation of the approach
class GFG
{
// Utility function to print
// the contents of the array
static void printArray(int []arr, int n)
{
for (int i = 0; i < n; i++)
System.out.print(arr[i] + " ");
}
// Function to find the required array
static void findArray(int []q, int n)
{
int ans;
int []arr = new int[n];
for (int k = 0, j = 0;
j < n / 4; j++)
{
ans = q[k] ^ q[k + 3];
arr[k + 1] = q[k + 1] ^ ans;
arr[k + 2] = q[k + 2] ^ ans;
arr[k] = q[k] ^ ((arr[k + 1]) ^
(arr[k + 2]));
arr[k + 3] = q[k + 3] ^ (arr[k + 1] ^
arr[k + 2]);
k += 4;
}
// Print the array
printArray(arr, n);
}
// Driver code
public static void main(String args[])
{
int []q = { 4, 1, 7, 0 };
int n = q.length;
findArray(q, n);
}
}
// This code is contributed
// by Akanksha Rai
Python3
# Python 3 implementation of the approach
# Utility function to print the
# contents of the array
def printArray(arr, n):
for i in range(n):
print(arr[i], end = " ")
# Function to find the required array
def findArray(q, n):
arr = [None] * n
k = 0
for j in range(int(n / 4)):
ans = q[k] ^ q[k + 3]
arr[k + 1] = q[k + 1] ^ ans
arr[k + 2] = q[k + 2] ^ ans
arr[k] = q[k] ^ ((arr[k + 1]) ^
(arr[k + 2]))
arr[k + 3] = q[k + 3] ^ (arr[k + 1] ^
arr[k + 2])
k += 4
# Print the array
printArray(arr, n)
# Driver code
if __name__ == '__main__':
q = [4, 1, 7, 0]
n = len(q)
findArray(q, n)
# This code is contributed by
# Surendra_Gangwar
C#
// C# implementation of the approach
using System;
class GFG
{
// Utility function to print
// the contents of the array
static void printArray(int []arr, int n)
{
for (int i = 0; i < n; i++)
Console.Write(arr[i] + " ");
}
// Function to find the required array
static void findArray(int []q, int n)
{
int ans;
int []arr = new int[n] ;
for (int k = 0, j = 0; j < n / 4; j++)
{
ans = q[k] ^ q[k + 3];
arr[k + 1] = q[k + 1] ^ ans;
arr[k + 2] = q[k + 2] ^ ans;
arr[k] = q[k] ^ ((arr[k + 1]) ^ (arr[k + 2]));
arr[k + 3] = q[k + 3] ^ (arr[k + 1] ^ arr[k + 2]);
k += 4;
}
// Print the array
printArray(arr, n);
}
// Driver code
public static void Main()
{
int []q = { 4, 1, 7, 0 };
int n = q.Length ;
findArray(q, n);
}
}
// This code is contributed by Ryuga
PHP
2 5 3 6
时间复杂度: O(N)
辅助空间: O(N)