📌  相关文章
📜  使一半的异或等于另一半的子数组的数量

📅  最后修改于: 2021-10-27 09:00:01             🧑  作者: Mango

给定一个由N 个数字组成的数组,任务是找到给定数组的子数组的数量(子数组的大小应该是偶数),这样在将子数组分成相等的两半后,按位异或子数组的一半将等于另一半的按位异或

例子:

Input : N = 6, arr[] = {3, 2, 2, 3, 7, 6}
Output : 3
Valid sub-arrays are {3, 2, 2, 3}, {2, 2}, 
and {2, 3, 7, 6}

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

Input : N = 3, arr[] = {42, 4, 2}
Output : 0

方法:如果一个数组被分成相等的两半,其中一半的异或等于另一半,则意味着整个数组的异或应该为0,因为A^A = 0。 现在,解决上述问题找到从左边开始的给定数组的所有元素的前缀异或。

假设,一个子数组从l开始到r结束,那么 (r-l+1) 应该是even 。此外,要找到给定范围(l, r) 的XOR,减去 (l – 1) 处的前缀 XOR 和 r 处的前缀 XOR。

由于 (r – l + 1) 是偶数,因此,如果r是偶数,那么l应该是奇数,反之亦然。现在,将您的前缀分为两组,一组应该是奇数索引的前缀组,另一组应该是偶数索引。现在,开始从左到右遍历前缀数组,看看这个特定的前缀 A 在其各自的组中已经出现了多少次,即偶数索引处的前缀应在偶数前缀组中检查,奇数索引处的前缀应在奇数前缀组中检查(因为如果r是偶数,则 ( l -1) 也是偶数,如果r是奇数,则应用类似的逻辑)。

下面是上述方法的实现:

C++
// C++ program to find number of subarrays such that
// XOR of one half is equal to the other
 
#include 
using namespace std;
 
// Function to find number of subarrays such that
// XOR of one half is equal to the other
int findSubarrCnt(int arr[], int n)
{
    // Variables to store answer and current XOR's
    int ans = 0, XOR = 0;
 
    // Array to store prefix XOR's
    int prefix[n];
 
    for (int i = 0; i < n; ++i) {
 
        // Calculate XOR until this index
        XOR = XOR ^ arr[i];
 
        // Store the XOR in prefix array
        prefix[i] = XOR;
    }
 
    // Create groups for odd indexes and even indexes
    unordered_map oddGroup, evenGroup;
 
    // Initialize occurrence of 0 in oddGroup as 1
    // because it will be used in case our
    // subarray has l = 0
    oddGroup[0] = 1;
 
    for (int i = 0; i < n; ++i) {
 
        if (i & 1) {
 
            // Check the frequency of current prefix
            // XOR in oddGroup and add it to the
            // answer
            ans += oddGroup[prefix[i]];
 
            // Update the frequency
            ++oddGroup[prefix[i]];
        }
        else {
 
            // Check the frequency of current prefix
            // XOR in evenGroup and add it to the
            // answer
            ans += evenGroup[prefix[i]];
 
            // Update the frequency
            ++evenGroup[prefix[i]];
        }
    }
 
    return ans;
}
 
// Driver Code
int main()
{
    int N = 6;
 
    int arr[] = { 3, 2, 2, 3, 7, 6 };
 
    cout << findSubarrCnt(arr, N);
 
    return 0;
}


Java
// JAVA program to find number of subarrays such that
// XOR of one half is equal to the other
import java.util.*;
 
class GFG
{
         
    // Function to find number of subarrays such that
    // XOR of one half is equal to the other
    static int findSubarrCnt(int arr[], int n)
    {
        // Variables to store answer and current XOR's
        int ans = 0, XOR = 0;
     
        // Array to store prefix XOR's
        int prefix[] = new int[n];
     
        for (int i = 0; i < n; ++i)
        {
     
            // Calculate XOR until this index
            XOR = XOR ^ arr[i];
     
            // Store the XOR in prefix array
            prefix[i] = XOR;
        }
     
        // Create groups for odd indexes and even indexes
        HashMap evenGroup = new HashMap<>();
        HashMap oddGroup = new HashMap<>();
         
 
        // Initialize occurrence of 0 in oddGroup as 1
        // because it will be used in case our
        // subarray has l = 0
        oddGroup.put(0, 1);
     
        for (int i = 0; i < n; ++i)
        {
     
            if (i % 2== 1)
            {
     
                // Check the frequency of current prefix
                // XOR in oddGroup and add it to the
                // answer
                if(oddGroup.containsKey(prefix[i]))
                {
                    ans += oddGroup.get(prefix[i]);
     
                    // Update the frequency
                    oddGroup.put(prefix[i],oddGroup.get(prefix[i] + 1));
                }
                else
                {
                    oddGroup.put(prefix[i], 1);
                }
                 
            }
            else
            {
     
                // Check the frequency of current prefix
                // XOR in evenGroup and add it to the
                // answer
                if(evenGroup.containsKey(prefix[i]))
                {
                    ans += evenGroup.get(prefix[i]);
     
                    // Update the frequency
                    evenGroup.put(prefix[i],evenGroup.get(prefix[i] + 1));
                }
                else
                {
                    evenGroup.put(prefix[i], 1);
                }
            }
        }
     
        return ans;
    }
     
    // Driver Code
    public static void main (String[] args)
    {
     
        int arr[] = { 3, 2, 2, 3, 7, 6 };
        int N = arr.length;
     
        System.out.println(findSubarrCnt(arr, N));
    }
}
 
// This code is contributed by ihritik


Python3
# Python3 program to find number of subarrays
# such that XOR of one half is equal to the other
 
# Function to find number of subarrays
# such that XOR of one half is equal
# to the other
def findSubarrCnt(arr, n) :
     
    # Variables to store answer
    # and current XOR's
    ans = 0; XOR = 0;
 
    # Array to store prefix XOR's
    prefix = [0] * n;
 
    for i in range(n) :
 
        # Calculate XOR until this index
        XOR = XOR ^ arr[i];
 
        # Store the XOR in prefix array
        prefix[i] = XOR;
     
    # Create groups for odd indexes and
    # even indexes
    oddGroup = dict.fromkeys(prefix, 0)
    evenGroup = dict.fromkeys(prefix, 0)
 
    # Initialize occurrence of 0 in oddGroup
    # as 1 because it will be used in case 
    # our subarray has l = 0
    oddGroup[0] = 1;
 
    for i in range(n) :
 
        if (i & 1) :
 
            # Check the frequency of current
            # prefix XOR in oddGroup and add
            # it to the answer
            ans += oddGroup[prefix[i]];
 
            # Update the frequency
            oddGroup[prefix[i]] += 1;
         
        else :
 
            # Check the frequency of current
            # prefix XOR in evenGroup and add
            # it to the answer
            ans += evenGroup[prefix[i]];
 
            # Update the frequency
            evenGroup[prefix[i]] += 1;
 
    return ans;
 
# Driver Code
if __name__ == "__main__" :
 
    N = 6;
 
    arr = [ 3, 2, 2, 3, 7, 6 ];
 
    print(findSubarrCnt(arr, N));
 
# This code is contributed by Ryuga


C#
// C# program to find number of subarrays such that
// XOR of one half is equal to the other
using System;
using System.Collections.Generic;
 
class GFG
{
         
    // Function to find number of subarrays such that
    // XOR of one half is equal to the other
    static int findSubarrCnt(int [] arr, int n)
    {
        // Variables to store answer and current XOR's
        int ans = 0, XOR = 0;
     
        // Array to store prefix XOR's
        int [] prefix = new int[n];
     
        for (int i = 0; i < n; ++i)
        {
     
            // Calculate XOR until this index
            XOR = XOR ^ arr[i];
     
            // Store the XOR in prefix array
            prefix[i] = XOR;
        }
     
        // Create groups for odd indexes and even indexes
        Dictionary evenGroup = new Dictionary();
        Dictionary oddGroup = new Dictionary();
 
        // Initialize occurrence of 0 in oddGroup as 1
        // because it will be used in case our
        // subarray has l = 0
        oddGroup[0] = 1;
     
        for (int i = 0; i < n; ++i)
        {
     
            if (i % 2== 1)
            {
     
                // Check the frequency of current prefix
                // XOR in oddGroup and add it to the
                // answer
                if(oddGroup.ContainsKey(prefix[i]))
                {
                    ans += oddGroup[prefix[i]];
     
                    // Update the frequency
                    oddGroup[prefix[i]]++;
                }
                else
                {
                    oddGroup[prefix[i]] = 1;
                }
                 
            }
            else
            {
     
                // Check the frequency of current prefix
                // XOR in evenGroup and add it to the
                // answer
                if(evenGroup.ContainsKey(prefix[i]))
                {
                    ans += evenGroup[prefix[i]];
     
                    // Update the frequency
                    evenGroup[prefix[i]]++;
                }
                else
                {
                    evenGroup[prefix[i]] = 1;
                }
            }
        }
     
        return ans;
    }
     
    // Driver Code
    public static void Main ()
    {
     
        int [] arr = { 3, 2, 2, 3, 7, 6 };
         
        int N = arr.Length;
     
        Console.WriteLine(findSubarrCnt(arr, N));
    }
}
 
// This code is contributed by ihritik


Javascript


输出:
3

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程