子阵列的异或(元素范围)

给定一个由n个整数组成的数组arr[]和一些查询。每个查询的形式为(L,R),其中L和R是数组的索引。查找子数组arr[L…R]的异或值,即当范围[L,R]中的所有元素都是异或时获得的值。假设基于0的索引,每个数组元素都是32位无符号整数。 例如:

null
Input : arr[] = {2, 5, 1, 6, 1, 2, 5}        L =  1, R = 4Output : 3The XOR value of arr[1...4] is 3.Input : arr[] = {2, 5, 1, 6, 1, 2, 5}        L = 0, R = 6Output : 6The XOR value of arr[0...6] is 6.

方法: A. 易于理解的 解决方案是为每个查询从索引L遍历给定数组到索引R。这导致处理每个查询的时间复杂度为O(n)。如果有q查询,那么所需的总时间将是O(q*n)。对于大量查询和大型数组,此解决方案不是最优的。 一 有效率的 解决方案是首先对数组进行预处理。两个观察结果将很有帮助:

  1. 问题陈述中提到,每个数组元素都是32位无符号数。因此,结果也将是一个32位无符号数。
  2. 当对多个位进行异或运算时,如果有奇数个1,则结果为1,否则结果为0。

使用观察1,创建一个大小为32*n的二维阵列cnt。该阵列将用于存储1s的计数。元素cnt[i][j]表示索引j之前第i位的1s数的计数,即在第i位位置的子阵列arr[0..j]中存在多少1s。 根据观察结果2,为了获得异或值,需要找到子阵列arr[L…R]中所有32位位置的1数。这可以在cnt阵列的帮助下完成。子阵列arr[L…R]中第i位位置的位数为cnt[i][R]–cnt[i][L-1]。如果第i位的1s数为奇数,则将在结果中设置第i位。然后,如果设置了第i位,则可通过将第i位对应的2的幂相加来获得结果。 根据该算法处理每个查询将需要O(32),即恒定时间。创建cnt阵列的预处理阶段需要O(n)个时间。因此,对于q查询,该解决方案的总时间复杂度为O(n+q)。 实施:

C++

#include <bits/stdc++.h>
using namespace std;
// Function to preprocess the array and find count of
// number of ones upto jth index for ith bit.
void preprocess( int arr[], int n, vector<vector< int > >& cnt)
{
int i, j;
// Run a loop for each bit position from
// 0 to 32.
for (i = 0; i < 32; i++) {
cnt[i][0] = 0;
for (j = 0; j < n; j++) {
if (j > 0) {
// store previous count of 1s
// for ith bit position.
cnt[i][j] = cnt[i][j - 1];
}
// Check if ith bit for jth element
// of array is set or not. If it is
// set then increase count of 1 for
// ith bit by 1.
if (arr[j] & (1 << i))
cnt[i][j]++;
}
}
}
// Function to find XOR value for a range of array elements.
int findXOR( int L, int R, const vector<vector< int > > cnt)
{
// variable to store final answer.
int ans = 0;
// variable to store number of 1s for ith bit
// in the range L to R.
int noOfOnes;
int i, j;
// Find number of 1s for each bit position from 0
// to 32.
for (i = 0; i < 32; i++) {
noOfOnes = cnt[i][R] - ((L > 0) ? cnt[i][L - 1] : 0);
// If number of 1s are odd then in the result
// ith bit will be set, i.e., 2^i will be present in
// the result. Add 2^i in ans variable.
if (noOfOnes & 1) {
ans += (1 << i);
}
}
return ans;
}
int main()
{
int arr[] = { 2, 5, 1, 6, 1, 2, 5 };
int n = sizeof (arr) / sizeof (arr[0]);
vector<vector< int > > cnt(32, vector< int >(n));
preprocess(arr, n, cnt);
int L = 1;
int R = 4;
cout << findXOR(L, R, cnt);
return 0;
}


JAVA

class GFG
{
// Function to preprocess the array and find count of
// number of ones upto jth index for ith bit.
static void preprocess( int arr[], int n, int [][] cnt)
{
int i, j;
// Run a loop for each bit position from
// 0 to 32.
for (i = 0 ; i < 32 ; i++)
{
cnt[i][ 0 ] = 0 ;
for (j = 0 ; j < n; j++)
{
if (j > 0 )
{
// store previous count of 1s
// for ith bit position.
cnt[i][j] = cnt[i][j - 1 ];
}
// Check if ith bit for jth element
// of array is set or not. If it is
// set then increase count of 1 for
// ith bit by 1.
if ((arr[j] & ( 1 << i)) >= 1 )
cnt[i][j]++;
}
}
}
// Function to find XOR value for a range of array elements.
static int findXOR( int L, int R, int [][] cnt)
{
// variable to store final answer.
int ans = 0 ;
// variable to store number of 1s for ith bit
// in the range L to R.
int noOfOnes;
int i, j;
// Find number of 1s for each bit position from 0
// to 32.
for (i = 0 ; i < 32 ; i++)
{
noOfOnes = cnt[i][R] - ((L > 0 ) ? cnt[i][L - 1 ] : 0 );
// If number of 1s are odd then in the result
// ith bit will be set, i.e., 2^i will be present in
// the result. Add 2^i in ans variable.
if (noOfOnes % 2 == 1 )
{
ans += ( 1 << i);
}
}
return ans;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 2 , 5 , 1 , 6 , 1 , 2 , 5 };
int n = arr.length;
int [][] cnt = new int [ 32 ][n];
preprocess(arr, n, cnt);
int L = 1 ;
int R = 4 ;
System.out.print(findXOR(L, R, cnt));
}
}
// This code is contributed by Rajput-Ji


Python3

# Function to preprocess the array and
# find count of number of ones upto
# jth index for ith bit.
def preprocess(arr, n, cnt):
# Run a loop for each bit position
# from 0 to 32.
for i in range ( 32 ):
cnt[i][ 0 ] = 0
for j in range (n):
if (j > 0 ):
# store previous count of 1s
# for ith bit position.
cnt[i][j] = cnt[i][j - 1 ]
# Check if ith bit for jth element
# of array is set or not. If it is
# set then increase count of 1 for
# ith bit by 1.
if (arr[j] & ( 1 << i)):
cnt[i][j] + = 1
# Function to find XOR value
# for a range of array elements.
def findXOR(L, R, cnt):
# variable to store final answer.
ans = 0
# variable to store number of 1s
# for ith bit in the range L to R.
noOfOnes = 0
# Find number of 1s for each
# bit position from 0 to 32.
for i in range ( 32 ):
if L > 0 :
noOfOnes = cnt[i][R] - cnt[i][L - 1 ]
else :
noOfOnes = cnt[i][R]
# If number of 1s are odd then in the result
# ith bit will be set, i.e., 2^i will be
# present in the result. Add 2^i in ans variable.
if (noOfOnes & 1 ):
ans + = ( 1 << i)
return ans
# Driver Code
arr = [ 2 , 5 , 1 , 6 , 1 , 2 , 5 ]
n = len (arr)
cnt = [[ 0 for i in range (n)]
for i in range ( 32 )]
preprocess(arr, n, cnt)
L = 1
R = 4
print (findXOR(L, R, cnt))
# This code is contributed by Mohit Kumar


C#

using System;
class GFG
{
// Function to preprocess the array and find count of
// number of ones upto jth index for ith bit.
static void preprocess( int []arr, int n, int [,] cnt)
{
int i, j;
// Run a loop for each bit position from
// 0 to 32.
for (i = 0; i < 32; i++)
{
cnt[i, 0] = 0;
for (j = 0; j < n; j++)
{
if (j > 0)
{
// store previous count of 1s
// for ith bit position.
cnt[i, j] = cnt[i, j - 1];
}
// Check if ith bit for jth element
// of array is set or not. If it is
// set then increase count of 1 for
// ith bit by 1.
if ((arr[j] & (1 << i)) >= 1)
cnt[i, j]++;
}
}
}
// Function to find XOR value for a range of array elements.
static int findXOR( int L, int R, int [,] cnt)
{
// variable to store readonly answer.
int ans = 0;
// variable to store number of 1s for ith bit
// in the range L to R.
int noOfOnes;
int i;
// Find number of 1s for each bit position from 0
// to 32.
for (i = 0; i < 32; i++)
{
noOfOnes = cnt[i, R] - ((L > 0) ? cnt[i, L - 1] : 0);
// If number of 1s are odd then in the result
// ith bit will be set, i.e., 2^i will be present in
// the result. Add 2^i in ans variable.
if (noOfOnes % 2 == 1)
{
ans += (1 << i);
}
}
return ans;
}
// Driver code
public static void Main(String[] args)
{
int []arr = { 2, 5, 1, 6, 1, 2, 5 };
int n = arr.Length;
int [,] cnt = new int [32, n];
preprocess(arr, n, cnt);
int L = 1;
int R = 4;
Console.Write(findXOR(L, R, cnt));
}
}
// This code is contributed by Rajput-Ji


Javascript

<script>
// Function to preprocess the array and find count of
// number of ones upto jth index for ith bit.
function preprocess(arr, n, cnt)
{
var i, j;
// Run a loop for each bit position from
// 0 to 32.
for (i = 0; i < 32; i++) {
cnt[i][0] = 0;
for (j = 0; j < n; j++) {
if (j > 0) {
// store previous count of 1s
// for ith bit position.
cnt[i][j] = cnt[i][j - 1];
}
// Check if ith bit for jth element
// of array is set or not. If it is
// set then increase count of 1 for
// ith bit by 1.
if (arr[j] & (1 << i))
cnt[i][j]++;
}
}
}
// Function to find XOR value for a range of array elements.
function findXOR(L, R, cnt)
{
// variable to store final answer.
var ans = 0;
// variable to store number of 1s for ith bit
// in the range L to R.
var noOfOnes;
var i, j;
// Find number of 1s for each bit position from 0
// to 32.
for (i = 0; i < 32; i++) {
noOfOnes = cnt[i][R] - ((L > 0) ? cnt[i][L - 1] : 0);
// If number of 1s are odd then in the result
// ith bit will be set, i.e., 2^i will be present in
// the result. Add 2^i in ans variable.
if (noOfOnes & 1) {
ans += (1 << i);
}
}
return ans;
}
var arr = [ 2, 5, 1, 6, 1, 2, 5 ];
var n = arr.length;
var cnt = Array.from( Array(32), () => Array(n));
preprocess(arr, n, cnt);
var L = 1;
var R = 4;
document.write( findXOR(L, R, cnt));
// This code is contributed by itsok.
</script>


输出:

3

时间复杂性: O(n+q) 辅助空间: O(n)

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享