如何报告异或为零的子数组的索引?
How to report the indices of a sub array whose xor is zero?
输入数组:5,2,7,100,1090,1,3,6,4,1062(0索引数组(
任务:对于给定的正整数序列,我想找到三元组 (i,j,k( 的数量,使得 1 ≤ i A[i]^...^A[j]−1=A[j]^A[
j]+1^...^A[k], 其中 ^ 表示按位 XOR。
我已经在C++中使用数组和映射尝试了prefix_xor问题,但我仍然需要提高时间复杂度。
cin >> n;
int A[n];
ll count = 0;
unordered_map<int, vector<int>> map_table;
for (int i = 0; i < n; ++i)
cin >> A[i];
map_table[A[0]].push_back(0);
for (int i = 1; i < n; ++i)
{
A[i] = A[i] ^ A[i-1];
if (!A[i])
count += i;
map_table[A[i]].push_back(i);
}
unordered_map<int, vector<int>>::iterator i2;
for (i2 = map_table.begin(); i2 != map_table.end(); ++i2)
{
int size = i2->second.size();
if (size >= 2)
{
for (int i = 0; i < size-1; ++i)
{
for (int k = i+1; k < size; ++k)
count += ((i2->second[k])-(i2->second[i])-1);
}
}
}
cout << count << 'n';
在此示例中,答案是 20
[0,2], [5,8], [0,9], [3,9]
异或(5, 2, 7( = 0;异或(1, 3, 6, 4( = 0;异或(100, 1090, ....1062( = 0;异或(5, 2, 7 ....1062( = 0
我将优化您代码的这一部分:
for (int i = 0; i < size-1; ++i)
{
for (int k = i+1; k < size; ++k)
count += ((i2->second[k])-(i2->second[i])-1);
}
请注意,您基本上是在尝试找到数组中每对数字之间的差异之和(i2->second
(。你在O(n^2)
中这样做,但如果我们稍微操纵一下公式,我们可以做得更快。
假设我们的数组(我们现在称之为 a
(的长度为 n
。我们现在只关注第 i
个元素(0 索引(,我们将计算它从总和中添加和减去的总次数。对于每j < i
,总和将包括a[i] - a[j]
。类似地,对于每j > i
,总和包括a[j] - a[i]
。在前一种情况下,a[i]
总共添加 i
次。在后一种情况下,a[i]
总共减去 n - i - 1
次。因此,总和中的a[i]
系数(添加次数减去减去的次数(为 i - (n - i - 1) == 2 * i - n + 1
。将其乘以每个元素并将所有内容相加,就可以得到答案(在调整-1
部分之后(。
现在对于复杂性,此算法将针对一个前缀 XOR 值O(n)
,其中n
是该值出现的次数。由于每个前缀 XOR 值出现的次数将加起来与原始数组的长度相加,因此在创建映射后,总复杂度是线性的。
下面是一个请求的示例:
假设数组有五个元素,a[0...4]
.如果我们写出您尝试计算的总和,它看起来像这样:
(a[1] - a[0]) + (a[2] - a[0]) + (a[3] - a[0]) + (a[4] - a[0])
+ (a[2] - a[1]) + (a[3] - a[1]) + (a[4] - a[1])
+ (a[3] - a[2]) + (a[4] - a[2])
+ (a[4] - a[3])
我们稍后会处理-1
。如果我们像术语一样分组,它看起来像这样:
-4 * a[0] + -2 * a[1] + 0 * a[2] + 2 * a[3] + 4 * a[4]
请注意,项的系数通过上述公式与该项的索引相关。因此,我们不是遍历每一对元素,而是计算这个缩短的表达式。在原始问题中,您需要为每对元素减去一个,因此我们可以从结果中减去元素对的数量。
- 数组索引的值没有增加
- 并行用于C++17中数组索引范围内的循环
- 数组索引重载错误
- 通过指针与数组引用扩展数组索引序列
- SIGSEGV, 分段错误. 而 printf() 数组索引的值
- 缓冲区溢出 - 数组索引越界(严重)
- 为什么C++数组索引值是有符号的,而不是围绕size_t类型构建的(或者我错了)
- 查找下一个具有真值C++的数组索引
- 在编译时自动生成用于稀疏数组索引的switch语句
- 在数组索引上引发异常
- C++ 将二维数组索引与条件语句中的函数值进行比较
- 平衡数组索引,同时从左和右对数组求和
- 为什么C ,Devstudio,数组索引工作
- 如何对同一数组索引下的结构成员进行排序?
- 我想返回数组索引,而不是数组值
- C++相当于 Python 的:用于数组索引
- 分段错误:为什么这里的数组索引越界了
- 数组索引在地图上不是整数
- 根据用户输入的每个字母添加到数组索引
- C 数组索引