给定范围[L,R] ,任务是查找给定范围内所有整数的XOR,即(L)^(L + 1)^(L + 2)^…^(R)
例子:
Input: L = 1, R = 4
Output: 4
1 ^ 2 ^ 3 ^ 4 = 4
Input: L = 3, R = 9
Output: 2
一个简单的解决方案是从L到R迭代查找所有数字的XOR。这将花费线性时间。
更好的解决方案是首先找到整数R中的最高有效位。我们的答案不能比“ R”大得多。对于介于0和MSB(含)之间的每个位“ i”,我们将尝试确定L和R(含)之间的整数个数的奇偶校验,以使第“ i”个位被设置。如果计数为奇数,则还将设置最终答案的第i个位。
现在真正的问题是,对于第一个问题,我们如何确定计数的奇偶性?
首先,让我们看一下前16个整数的二进制表示形式。
0: 0000
1: 0001
2: 0010
3: 0011
4: 0100
5: 0101
6: 0110
7: 0111
8: 1000
9: 1001
10: 1010
11: 1011
12: 1100
13: 1101
14: 1110
15: 1111
很容易注意到,第i个位的状态在每2个i数之后发生变化。我们将使用这个想法来预测一些整数的计数与第i位设置范围从左至右的包容性。
这里有两种情况:
- 情况1(i!= 0):我们尝试确定是否设置了L的第i位。如果已设置,我们将尝试查找L和L + 2 i(含)之间的数量计数的奇偶性,以使它们的第i位被设置。如果L的第i位被置位且L为奇数,则此计数将为奇数,否则为偶数。
类似地,对于R,我们尝试确定R – 2 i和R之间的多个元素的计数的奇偶性,从而设置它们的第i位。如果L的第i位被设置且L为偶数,则此计数将为奇数,否则为偶数。
我们忽略它们之间的所有其他整数,因为它们将具有偶数个设置了第i位的整数。 - 情况2(i = 0):在这里,我们有以下情况:
- 如果L和R均为奇数,则设置第0位的整数的计数为(R – L)/ 2 + 1
- 在任何其他情况下,计数将为floor((R – L + 1)/ 2) 。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the
// most significant bit
int msb(int x)
{
int ret = 0;
while ((x >> (ret + 1)) != 0)
ret++;
return ret;
}
// Function to return the required XOR
int xorRange(int l, int r)
{
// Finding the MSB
int max_bit = msb(r);
// Value of the current bit to be added
int mul = 2;
// To store the final answer
int ans = 0;
// Loop for case 1
for (int i = 1; i <= max_bit; i++) {
// Edge case when both the integers
// lie in the same segment of continuous
// 1s
if ((l / mul) * mul == (r / mul) * mul) {
if (((l & (1 << i)) != 0) && (r - l + 1) % 2 == 1)
ans += mul;
mul *= 2;
continue;
}
// To store whether parity of count is odd
bool odd_c = 0;
if (((l & (1 << i)) != 0) && l % 2 == 1)
odd_c = (odd_c ^ 1);
if (((r & (1 << i)) != 0) && r % 2 == 0)
odd_c = (odd_c ^ 1);
// Updating the answer if parity is odd
if (odd_c)
ans += mul;
// Updating the number to be added
mul *= 2;
}
// Case 2
int zero_bit_cnt = zero_bit_cnt = (r - l + 1) / 2;
if (l % 2 == 1 && r % 2 == 1)
zero_bit_cnt++;
if (zero_bit_cnt % 2 == 1)
ans++;
return ans;
}
// Driver code
int main()
{
int l = 1, r = 4;
// Final answer
cout << xorRange(l, r);
return 0;
}
Java
// Java implementation of the approach
class GFG
{
// Function to return the
// most significant bit
static int msb(int x)
{
int ret = 0;
while ((x >> (ret + 1)) != 0)
ret++;
return ret;
}
// Function to return the required XOR
static int xorRange(int l, int r)
{
// Finding the MSB
int max_bit = msb(r);
// Value of the current bit to be added
int mul = 2;
// To store the final answer
int ans = 0;
// Loop for case 1
for (int i = 1; i <= max_bit; i++)
{
// Edge case when both the integers
// lie in the same segment of continuous
// 1s
if ((l / mul) * mul == (r / mul) * mul)
{
if (((l & (1 << i)) != 0) && (r - l + 1) % 2 == 1)
ans += mul;
mul *= 2;
continue;
}
// To store whether parity of count is odd
int odd_c = 0;
if (((l & (1 << i)) != 0) && l % 2 == 1)
odd_c = (odd_c ^ 1);
if (((r & (1 << i)) != 0) && r % 2 == 0)
odd_c = (odd_c ^ 1);
// Updating the answer if parity is odd
if (odd_c!=0)
ans += mul;
// Updating the number to be added
mul *= 2;
}
// Case 2
int zero_bit_cnt = zero_bit_cnt = (r - l + 1) / 2;
if (l % 2 == 1 && r % 2 == 1)
zero_bit_cnt++;
if (zero_bit_cnt % 2 == 1)
ans++;
return ans;
}
// Driver code
public static void main(String args[])
{
int l = 1, r = 4;
// Final answer
System.out.print(xorRange(l, r));
}
}
// This code is contributed by Arnab Kundu
Python3
# Python3 implementation of the approach
# Function to return the most significant bit
def msb(x) :
ret = 0
while ((x >> (ret + 1)) != 0) :
ret = ret + 1
return ret
# Function to return the required XOR
def xorRange(l, r) :
# Finding the MSB
max_bit = msb(r)
# Value of the current bit to be added
mul = 2
# To store the final answer
ans = 0
# Loop for case 1
for i in range (1, max_bit + 1) :
# Edge case when both the integers
# lie in the same segment of continuous
# 1s
if ((l // mul) * mul == (r // mul) * mul) :
if ((((l & (1 << i)) != 0) and
(r - l + 1) % 2 == 1)) :
ans = ans + mul
mul = mul * 2
continue
# To store whether parity of count is odd
odd_c = 0
if (((l & (1 << i)) != 0) and l % 2 == 1) :
odd_c = (odd_c ^ 1)
if (((r & (1 << i)) != 0) and r % 2 == 0) :
odd_c = (odd_c ^ 1)
# Updating the answer if parity is odd
if (odd_c) :
ans = ans + mul
# Updating the number to be added
mul = mul * 2
# Case 2
zero_bit_cnt = (r - l + 1) // 2
if ((l % 2 == 1 ) and (r % 2 == 1)) :
zero_bit_cnt = zero_bit_cnt + 1
if (zero_bit_cnt % 2 == 1):
ans = ans + 1
return ans
# Driver code
l = 1
r = 4
# Final answer
print(xorRange(l, r))
# This code is contributed by ihritik
C#
// C# implementation of the approach
using System;
class GFG
{
// Function to return the
// most significant bit
static int msb(int x)
{
int ret = 0;
while ((x >> (ret + 1)) != 0)
ret++;
return ret;
}
// Function to return the required XOR
static int xorRange(int l, int r)
{
// Finding the MSB
int max_bit = msb(r);
// Value of the current bit to be added
int mul = 2;
// To store the final answer
int ans = 0;
// Loop for case 1
for (int i = 1; i <= max_bit; i++)
{
// Edge case when both the integers
// lie in the same segment of continuous
// 1s
if ((l / mul) * mul == (r / mul) * mul)
{
if (((l & (1 << i)) != 0) && (r - l + 1) % 2 == 1)
ans += mul;
mul *= 2;
continue;
}
// To store whether parity of count is odd
int odd_c = 0;
if (((l & (1 << i)) != 0) && l % 2 == 1)
odd_c = (odd_c ^ 1);
if (((r & (1 << i)) != 0) && r % 2 == 0)
odd_c = (odd_c ^ 1);
// Updating the answer if parity is odd
if (odd_c!=0)
ans += mul;
// Updating the number to be added
mul *= 2;
}
// Case 2
int zero_bit_cnt = zero_bit_cnt = (r - l + 1) / 2;
if (l % 2 == 1 && r % 2 == 1)
zero_bit_cnt++;
if (zero_bit_cnt % 2 == 1)
ans++;
return ans;
}
// Driver code
public static void Main(String []args)
{
int l = 1, r = 4;
// Final answer
Console.Write(xorRange(l, r));
}
}
// This code contributed by Rajput-Ji
PHP
> ($ret + 1)) != 0)
$ret++;
return $ret;
}
// Function to return the required XOR
function xorRange($l, $r)
{
// Finding the MSB
$max_bit = msb($r);
// Value of the current bit to be added
$mul = 2;
// To store the final answer
$ans = 0;
// Loop for case 1
for ($i = 1; $i <= $max_bit; $i++)
{
// Edge case when both the integers
// lie in the same segment of continuous
// 1s
if ((int)(($l / $mul) * $mul) ==
(int)(($r / $mul) * $mul))
{
if ((($l & (1 << $i)) != 0) &&
($r - $l + 1) % 2 == 1)
$ans += $mul;
$mul *= 2;
continue;
}
// To store whether parity of count is odd
$odd_c = 0;
if ((($l & (1 << $i)) != 0) && $l % 2 == 1)
$odd_c = ($odd_c ^ 1);
if ((($r & (1 << $i)) != 0) && $r % 2 == 0)
$odd_c = ($odd_c ^ 1);
// Updating the answer if parity is odd
if ($odd_c)
$ans += $mul;
// Updating the number to be added
$mul *= 2;
}
// Case 2
$zero_bit_cnt = (int)(($r - $l + 1) / 2);
if ($l % 2 == 1 && $r % 2 == 1)
$zero_bit_cnt++;
if ($zero_bit_cnt % 2 == 1)
$ans++;
return $ans;
}
// Driver code
$l = 1;
$r = 4;
// Final answer
echo xorRange($l, $r);
// This code is contributed by mits
?>
Javascript
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the required XOR
long computeXOR(const int n)
{
// Modulus operator are expensive
// on most of the computers.
// n & 3 will be equivalent to n % 4
// n % 4
switch (n & 3) {
// If n is a multiple of 4
case 0:
return n;
// If n % 4 gives remainder 1
case 1:
return 1;
// If n % 4 gives remainder 2
case 2:
return n + 1;
// If n % 4 gives remainder 3
case 3:
return 0;
}
}
// Driver code
int main()
{
int l = 1, r = 4;
cout << (computeXOR(r) ^ computeXOR(l - 1));
return 0;
}
Java
// Java implementation of the approach
class GFG
{
// Function to return the required XOR
static long computeXOR(int n)
{
// Modulus operator are expensive
// on most of the computers.
// n & 3 will be equivalent to n % 4
// n % 4
int x = n & 3;
switch (x)
{
// If n is a multiple of 4
case 0:
return n;
// If n % 4 gives remainder 1
case 1:
return 1;
// If n % 4 gives remainder 2
case 2:
return n + 1;
// If n % 4 gives remainder 3
case 3:
return 0;
}
return 0;
}
// Driver code
public static void main(String args[])
{
int l = 1, r = 4;
System.out.println(computeXOR(r) ^
computeXOR(l - 1));
}
}
// This code is contributed by Ryuga
Python3
# Python3 implementation of the approach
# Function to return the required XOR
def computeXOR(n) :
# Modulus operator are expensive
# on most of the computers.
# n & 3 will be equivalent to n % 4
# n % 4
switch = {
# If n is a multiple of 4
0 : n,
# If n % 4 gives remainder 1
1 : 1,
# If n % 4 gives remainder 2
2: n + 1,
# If n % 4 gives remainder 3
3 : 0,
}
return switch.get( n & 3, "")
# Driver code
l = 1
r = 4
print(computeXOR(r) ^ computeXOR(l - 1))
# This code is contributed by ihritik
C#
// C# implementation of the approach
using System;
class GFG
{
// Function to return the required XOR
static long computeXOR(int n)
{
// Modulus operator are expensive
// on most of the computers.
// n & 3 will be equivalent to n % 4
// n % 4
int x=n&3;
switch (x)
{
// If n is a multiple of 4
case 0:
return n;
// If n % 4 gives remainder 1
case 1:
return 1;
// If n % 4 gives remainder 2
case 2:
return n + 1;
// If n % 4 gives remainder 3
case 3:
return 0;
}
return 0;
}
// Driver code
static void Main()
{
int l = 1, r = 4;
Console.WriteLine(computeXOR(r) ^ computeXOR(l - 1));
}
}
// This code is contributed by mits
PHP
Javascript
4
时间复杂度: O(log 2 (R))
高效的方法:令F(N)为计算所有小于或等于N的自然数的XOR的函数。因此,对于范围(LR),答案将为F(R)^ F(L-1) 。
如本文所述,可以在O(1)中找到任意给定数字的该函数的值。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the required XOR
long computeXOR(const int n)
{
// Modulus operator are expensive
// on most of the computers.
// n & 3 will be equivalent to n % 4
// n % 4
switch (n & 3) {
// If n is a multiple of 4
case 0:
return n;
// If n % 4 gives remainder 1
case 1:
return 1;
// If n % 4 gives remainder 2
case 2:
return n + 1;
// If n % 4 gives remainder 3
case 3:
return 0;
}
}
// Driver code
int main()
{
int l = 1, r = 4;
cout << (computeXOR(r) ^ computeXOR(l - 1));
return 0;
}
Java
// Java implementation of the approach
class GFG
{
// Function to return the required XOR
static long computeXOR(int n)
{
// Modulus operator are expensive
// on most of the computers.
// n & 3 will be equivalent to n % 4
// n % 4
int x = n & 3;
switch (x)
{
// If n is a multiple of 4
case 0:
return n;
// If n % 4 gives remainder 1
case 1:
return 1;
// If n % 4 gives remainder 2
case 2:
return n + 1;
// If n % 4 gives remainder 3
case 3:
return 0;
}
return 0;
}
// Driver code
public static void main(String args[])
{
int l = 1, r = 4;
System.out.println(computeXOR(r) ^
computeXOR(l - 1));
}
}
// This code is contributed by Ryuga
Python3
# Python3 implementation of the approach
# Function to return the required XOR
def computeXOR(n) :
# Modulus operator are expensive
# on most of the computers.
# n & 3 will be equivalent to n % 4
# n % 4
switch = {
# If n is a multiple of 4
0 : n,
# If n % 4 gives remainder 1
1 : 1,
# If n % 4 gives remainder 2
2: n + 1,
# If n % 4 gives remainder 3
3 : 0,
}
return switch.get( n & 3, "")
# Driver code
l = 1
r = 4
print(computeXOR(r) ^ computeXOR(l - 1))
# This code is contributed by ihritik
C#
// C# implementation of the approach
using System;
class GFG
{
// Function to return the required XOR
static long computeXOR(int n)
{
// Modulus operator are expensive
// on most of the computers.
// n & 3 will be equivalent to n % 4
// n % 4
int x=n&3;
switch (x)
{
// If n is a multiple of 4
case 0:
return n;
// If n % 4 gives remainder 1
case 1:
return 1;
// If n % 4 gives remainder 2
case 2:
return n + 1;
// If n % 4 gives remainder 3
case 3:
return 0;
}
return 0;
}
// Driver code
static void Main()
{
int l = 1, r = 4;
Console.WriteLine(computeXOR(r) ^ computeXOR(l - 1));
}
}
// This code is contributed by mits
的PHP
Java脚本
4