给定一个包含N个正整数的数组,任务是找到该数组所有子数组的XOR之和。
例子:
Input : arr[] = {1, 3, 7, 9, 8, 7}
Output : 128
Input : arr[] = {3, 8, 13}
Output : 46
Explanation for second test-case:
XOR of {3} = 3
XOR of {3, 8} = 11
XOR of {3, 8, 13} = 6
XOR of {8} = 8
XOR of {8, 13} = 5
XOR of {13} = 13
Sum = 3 + 11 + 6 + 8 + 5 + 13 = 46
简单的解决方案:一个简单的解决方案是生成所有子数组,然后遍历所有子数组以找到所需的XOR值,然后对其求和。该方法的时间复杂度将为O(n 3 )。
更好的解决方案:更好的解决方案是使用前缀数组,即对于数组’arr []’的每个索引’i’,创建一个前缀数组来存储数组’arr []左端所有元素的XOR。 ]”到“ arr []”的第i个元素。创建前缀数组将花费O(N)的时间。
现在,使用此前缀数组,我们可以找到O(1)时间中任何子数组的XOR值。
我们可以使用以下公式找到从索引l到r的XOR:
if l is not zero
XOR = prefix[r] ^ prefix[l-1]
else
XOR = prefix[r].
在此之后,我们要做的就是总结所有子数组的XOR值。
由于子阵列的总数为(N 2 )阶,因此此方法的时间复杂度将为O(N 2 )。
最佳解决方案:为了更好地理解,我们假设元素的任何位都由变量“ i”表示,并且变量“ sum”用于存储最终和。
这里的想法是,我们将尝试找到第i个位设置的XOR值的数量。让我们假设,存在第i个位设置为’S i ‘的子阵列。对于,第i位,总和可以更新为总和+ =(2 i * S) 。
那么,问题是如何实现上述想法?
我们会将任务分为多个步骤。在每一步,我们将尝试找到第i个位设置的XOR值的数量。
现在,我们将每个步骤细分为几个子步骤。在每个子步骤中,我们将尝试查找从索引“ j”(其中j在0到n – 1之间变化)开始的子数组的数量,并将其第i位设置为它们的XOR值。因为要设置第i个比特,所以应该在第i个比特中设置奇数个子阵列的元素。
对于所有的位,在可变c_odd,我们将存储从j = 0开始,其中i在奇数元件的第i位组子阵列的数目的计数。然后,我们将遍历数组的所有元素,并在需要时更新c_odd的值。如果到达设置了第i位的元素“ j”,则将c_odd更新为c_odd =(n – j – c_odd) 。其因为,由于我们遇到了一组位,子阵列的与i个元素个比特组将切换到多个子阵列的具有奇数个与i个元素个位组中的偶数数目的数目。
以下是此方法的实现:
C++
// C++ program to find the sum of XOR of
// all subarray of the array
#include
#include
using namespace std;
// Function to calculate the sum of XOR
// of all subarrays
int findXorSum(int arr[], int n)
{
// variable to store
// the final sum
int sum = 0;
// multiplier
int mul = 1;
for (int i = 0; i < 30; i++) {
// variable to store number of
// sub-arrays with odd number of elements
// with ith bits starting from the first
// element to the end of the array
int c_odd = 0;
// variable to check the status
// of the odd-even count while
// calculating c_odd
bool odd = 0;
// loop to calculate initial
// value of c_odd
for (int j = 0; j < n; j++) {
if ((arr[j] & (1 << i)) > 0)
odd = (!odd);
if (odd)
c_odd++;
}
// loop to iterate through
// all the elements of the
// array and update sum
for (int j = 0; j < n; j++) {
sum += (mul * c_odd);
if ((arr[j] & (1 << i)) > 0)
c_odd = (n - j - c_odd);
}
// updating the multiplier
mul *= 2;
}
// returning the sum
return sum;
}
// Driver Code
int main()
{
int arr[] = { 3, 8, 13 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << findXorSum(arr, n);
return 0;
}
Java
// Java program to find the sum of XOR
// of all subarray of the array
import java.util.*;
class GFG
{
// Function to calculate the sum of XOR
// of all subarrays
static int findXorSum(int arr[], int n)
{
// variable to store
// the final sum
int sum = 0;
// multiplier
int mul = 1;
for (int i = 0; i < 30; i++)
{
// variable to store number of
// sub-arrays with odd number of elements
// with ith bits starting from the first
// element to the end of the array
int c_odd = 0;
// variable to check the status
// of the odd-even count while
// calculating c_odd
boolean odd = false;
// loop to calculate initial
// value of c_odd
for (int j = 0; j < n; j++)
{
if ((arr[j] & (1 << i)) > 0)
odd = (!odd);
if (odd)
c_odd++;
}
// loop to iterate through
// all the elements of the
// array and update sum
for (int j = 0; j < n; j++)
{
sum += (mul * c_odd);
if ((arr[j] & (1 << i)) > 0)
c_odd = (n - j - c_odd);
}
// updating the multiplier
mul *= 2;
}
// returning the sum
return sum;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 3, 8, 13 };
int n = arr.length;
System.out.println(findXorSum(arr, n));
}
}
// This code is contributed by Rituraj Jain.
Python3
# Python3 program to find the Sum of
# XOR of all subarray of the array
# Function to calculate the Sum of XOR
# of all subarrays
def findXorSum(arr, n):
# variable to store the final Sum
Sum = 0
# multiplier
mul = 1
for i in range(30):
# variable to store number of sub-arrays
# with odd number of elements with ith
# bits starting from the first element
# to the end of the array
c_odd = 0
# variable to check the status of the
# odd-even count while calculating c_odd
odd = 0
# loop to calculate initial
# value of c_odd
for j in range(n):
if ((arr[j] & (1 << i)) > 0):
odd = (~odd)
if (odd):
c_odd += 1
# loop to iterate through all the
# elements of the array and update Sum
for j in range(n):
Sum += (mul * c_odd)
if ((arr[j] & (1 << i)) > 0):
c_odd = (n - j - c_odd)
# updating the multiplier
mul *= 2
# returning the Sum
return Sum
# Driver Code
arr = [3, 8, 13]
n = len(arr)
print(findXorSum(arr, n))
# This code is contributed by Mohit Kumar
C#
// C# program to find the sum of XOR of
// all subarray of the array
using System;
class GFG
{
// Function to calculate the sum
// of XOR of all subarrays
static int findXorSum(int []arr, int n)
{
// variable to store
// the final sum
int sum = 0;
// multiplier
int mul = 1;
for (int i = 0; i < 30; i++)
{
// variable to store number of sub-arrays
// with odd number of elements with ith
// bits starting from the first element
// to the end of the array
int c_odd = 0;
// variable to check the status
// of the odd-even count while
// calculating c_odd
bool odd = false;
// loop to calculate initial
// value of c_odd
for (int j = 0; j < n; j++)
{
if ((arr[j] & (1 << i)) > 0)
odd = (!odd);
if (odd)
c_odd++;
}
// loop to iterate through
// all the elements of the
// array and update sum
for (int j = 0; j < n; j++)
{
sum += (mul * c_odd);
if ((arr[j] & (1 << i)) > 0)
c_odd = (n - j - c_odd);
}
// updating the multiplier
mul *= 2;
}
// returning the sum
return sum;
}
// Driver Code
static void Main()
{
int []arr = { 3, 8, 13 };
int n = arr.Length;
Console.WriteLine(findXorSum(arr, n));
}
}
// This code is contributed by mits
PHP
0)
$odd = (!$odd);
if ($odd)
$c_odd++;
}
// loop to iterate through
// all the elements of the
// array and update sum
for ($j = 0; $j < $n; $j++)
{
$sum += ($mul * $c_odd);
if (($arr[$j] & (1 << $i)) > 0)
$c_odd = ($n - $j - $c_odd);
}
// updating the multiplier
$mul *= 2;
}
// returning the sum
return $sum;
}
// Driver Code
$arr = array(3, 8, 13);
$n = sizeof($arr);
echo findXorSum($arr, $n);
// This code is contributed by Ryuga
?>
Javascript
46
时间复杂度:O(N)
如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。