📜  给定数组范围的XOR之和最大的数字

📅  最后修改于: 2021-04-26 04:59:46             🧑  作者: Mango

系统会为您提供N个整数和Q个查询的序列。在每个查询中,给您两个参数L和R。您必须找到最小的整数X,以使0 <= X <2 ^ 31且x与所有元素的XOR之和为范围[L,R]最大可能的。


例子 :

Input  : A = {20, 11, 18, 2, 13}
         Three queries as (L, R) pairs
         1 3
         3 5
         2 4
Output : 2147483629
         2147483645
         2147483645

方法:每个元素和X的二进制表示,我们可以观察到每个位都是独立的,并且可以通过迭代每个位来解决问题。现在基本上,对于每个位,我们需要计算给定范围内的1和0的数量,如果1的数量更多,则必须将X的该位设置为0,以使x与x或x或之后的和最大。 0的数量更多,那么您必须将X的该位设置为1。如果1和0的数量相等,那么我们可以将X的该位设置为1或0中的任何一个,因为这不会影响总和,但是我们必须最小化X的值,因此我们将使用该位0。

现在,为了优化解决方案,我们可以通过制作前缀数组来预先计算数字的每个位位置上的1的计数,该前缀数组将花费O(n)时间。现在,对于每个查询,从1到Rth位置的数字都是1的数量–直到第(L-1)位置的1的数量。

C++
// CPP program to find smallest integer X
// such that sum of its XOR with range is
// maximum.
#include 
using namespace std;
  
#define MAX 2147483647
int one[100001][32];
  
// Function to make prefix array which 
// counts 1's of each bit up to that number
void make_prefix(int A[], int n)
{
    for (int j = 0; j < 32; j++)
        one[0][j] = 0;
  
    // Making a prefix array which sums
    // number of 1's up to that position
    for (int i = 1; i <= n; i++) 
    {
        int a = A[i - 1];
        for (int j = 0; j < 32; j++) 
        {
            int x = pow(2, j);
  
            // If j-th bit of a number is set then
            // add one to previously counted 1's
            if (a & x)
                one[i][j] = 1 + one[i - 1][j];
            else
                one[i][j] = one[i - 1][j];
        }
    }
}
  
// Function to find X
int Solve(int L, int R)
{
    int l = L, r = R;
    int tot_bits = r - l + 1;
  
    // Initially taking maximum value all bits 1
    int X = MAX;
  
    // Iterating over each bit
    for (int i = 0; i < 31; i++) 
    {
  
        // get 1's at ith bit between the 
        // range L-R by subtracting 1's till
        // Rth number - 1's till L-1th number
        int x = one[r][i] - one[l - 1][i];
  
        // If 1's are more than or equal to 0's
        // then unset the ith bit from answer
        if (x >= tot_bits - x) 
        {
            int ith_bit = pow(2, i);
  
            // Set ith bit to 0 by doing
            // Xor with 1
            X = X ^ ith_bit;
        }
    }
    return X;
}
  
// Driver program
int main()
{
    // Taking inputs
    int n = 5, q = 3;
    int A[] = { 210, 11, 48, 22, 133 };
    int L[] = { 1, 4, 2 }, R[] = { 3, 14, 4 };
  
    make_prefix(A, n);
  
    for (int j = 0; j < q; j++)
        cout << Solve(L[j], R[j]) << endl;
  
    return 0;
}


Java
// Java program to find smallest integer X
// such that sum of its XOR with range is
// maximum.
import java.lang.Math;
  
class GFG {
      
    private static final int MAX = 2147483647;
    static int[][] one = new int[100001][32];
      
    // Function to make prefix array which counts
    // 1's of each bit up to that number
    static void make_prefix(int A[], int n)
    {
        for (int j = 0; j < 32; j++)
            one[0][j] = 0;
  
        // Making a prefix array which sums
        // number of 1's up to that position
        for (int i = 1; i <= n; i++) 
        {
            int a = A[i - 1];
            for (int j = 0; j < 32; j++) 
            {
                int x = (int)Math.pow(2, j);
  
                // If j-th bit of a number is set then
                // add one to previously counted 1's
                if ((a & x) != 0)
                    one[i][j] = 1 + one[i - 1][j];
                else
                    one[i][j] = one[i - 1][j];
            }
        }
    }
  
    // Function to find X
    static int Solve(int L, int R)
    {
        int l = L, r = R;
        int tot_bits = r - l + 1;
  
        // Initially taking maximum 
        // value all bits 1
        int X = MAX;
  
        // Iterating over each bit
        for (int i = 0; i < 31; i++) 
        {
  
            // get 1's at ith bit between the range
            // L-R by subtracting 1's till
            // Rth number - 1's till L-1th number
            int x = one[r][i] - one[l - 1][i];
  
            // If 1's are more than or equal to 0's
            // then unset the ith bit from answer
            if (x >= tot_bits - x) 
            {
                int ith_bit = (int)Math.pow(2, i);
  
                // Set ith bit to 0 by 
                // doing Xor with 1
                X = X ^ ith_bit;
            }
        }
        return X;
    }
  
    // Driver program
    public static void main(String[] args)
    {
        // Taking inputs
        int n = 5, q = 3;
        int A[] = { 210, 11, 48, 22, 133 };
        int L[] = { 1, 4, 2 }, R[] = { 3, 14, 4 };
  
        make_prefix(A, n);
  
        for (int j = 0; j < q; j++)
            System.out.println(Solve(L[j], R[j]));
    }
}
  
// This code is contributed by Smitha


Python3
# Python3 program to find smallest integer X
# such that sum of its XOR with range is
# maximum.
import math
  
one = [[0 for x in range(32)] 
      for y in range(100001)] 
MAX = 2147483647
  
# Function to make prefix array 
# which counts 1's of each bit 
# up to that number
def make_prefix(A, n) :
    global one, MAX
      
    for j in range(0 , 32) :
        one[0][j] = 0
  
    # Making a prefix array which 
    # sums number of 1's up to 
    # that position
    for i in range(1, n+1) : 
        a = A[i - 1]
        for j in range(0 , 32) :
          
            x = int(math.pow(2, j))
  
            # If j-th bit of a number 
            # is set then add one to
            # previously counted 1's
            if (a & x) :
                one[i][j] = 1 + one[i - 1][j]
            else :
                one[i][j] = one[i - 1][j]
          
# Function to find X
def Solve(L, R) :
  
    global one, MAX
    l = L 
    r = R
    tot_bits = r - l + 1
  
    # Initially taking maximum
    # value all bits 1
    X = MAX
  
    # Iterating over each bit
    for i in range(0, 31) :
      
        # get 1's at ith bit between the 
        # range L-R by subtracting 1's till
        # Rth number - 1's till L-1th number
          
        x = one[r][i] - one[l - 1][i]
  
        # If 1's are more than or equal 
        # to 0's then unset the ith bit
        # from answer
        if (x >= (tot_bits - x)) :
              
            ith_bit = pow(2, i)
  
            # Set ith bit to 0 by
            # doing Xor with 1
            X = X ^ ith_bit
    return X
  
# Driver Code
n = 5
q = 3
A = [ 210, 11, 48, 22, 133 ]
L = [ 1, 4, 2 ] 
R = [ 3, 14, 4 ]
  
make_prefix(A, n)
  
for j in range(0, q) :
    print (Solve(L[j], R[j]),end="\n")
      
# This code is contributed by 
# Manish Shaw(manishshaw1)


C#
// C# program to find smallest integer X
// such that sum of its XOR with range is
// maximum.
using System;
using System.Collections.Generic;
  
class GFG{
    static int MAX = 2147483647;
    static int [,]one = new int[100001,32];
      
    // Function to make prefix 
    // array which counts 1's 
    // of each bit up to that number
    static void make_prefix(int []A, int n)
    {
        for (int j = 0; j < 32; j++)
            one[0,j] = 0;
      
        // Making a prefix array which sums
        // number of 1's up to that position
        for (int i = 1; i <= n; i++) 
        {
            int a = A[i - 1];
            for (int j = 0; j < 32; j++) 
            {
                int x = (int)Math.Pow(2, j);
      
                // If j-th bit of a number is set then
                // add one to previously counted 1's
                if ((a & x) != 0)
                    one[i, j] = 1 + one[i - 1, j];
                else
                    one[i,j] = one[i - 1, j];
            }
        }
    }
      
    // Function to find X
    static int Solve(int L, int R)
    {
        int l = L, r = R;
        int tot_bits = r - l + 1;
      
        // Initially taking maximum
        // value all bits 1
        int X = MAX;
      
        // Iterating over each bit
        for (int i = 0; i < 31; i++) 
        {
      
            // get 1's at ith bit between the 
            // range L-R by subtracting 1's till
            // Rth number - 1's till L-1th number
            int x = one[r, i] - one[l - 1, i];
      
            // If 1's are more than or 
            // equal to 0's then unset
            // the ith bit from answer
            if (x >= tot_bits - x) 
            {
                int ith_bit = (int)Math.Pow(2, i);
      
                // Set ith bit to 0 by doing
                // Xor with 1
                X = X ^ ith_bit;
            }
        }
        return X;
    }
      
    // Driver Code
    public static void Main()
    {
          
        // Taking inputs
        int n = 5, q = 3;
        int []A = {210, 11, 48, 22, 133};
        int []L = {1, 4, 2};
        int []R = {3, 14, 4};
      
        make_prefix(A, n);
      
        for (int j = 0; j < q; j++)
            Console.WriteLine(Solve(L[j], R[j]));
    }
}
  
// This code is contributed by 
// Manish Shaw (manishshaw1)


PHP
= ($tot_bits - $x)) 
        {
            $ith_bit = pow(2, $i);
  
            // Set ith bit to 0 by
            // doing Xor with 1
            $X = $X ^ $ith_bit;
        }
    }
    return $X;
}
  
// Driver Code
$n = 5; $q = 3;
$A = [ 210, 11, 48, 22, 133 ];
$L = [ 1, 4, 2 ]; 
$R = [ 3, 14, 4 ];
  
make_prefix($A, $n);
  
for ($j = 0; $j < $q; $j++)
    echo (Solve($L[$j], $R[$j]). "\n");
      
// This code is contributed by 
// Manish Shaw(manishshaw1)
?>


输出 :

2147483629
2147483647
2147483629