在the approach described below的实现中,我没有得到这两个循环如何考虑测试用例的哪一部分,我的意思是这两个循环如何涵盖所有可能性。请帮助
问题链接xor subbarray
// loop to calculate initial
// value of c_odd
for (int j = 0; j < n; j++) {
if ((arr[j] & (1 << i)) > 0)
odd = (!odd);
if (odd)
c_odd++;
}
和这个
for (int j = 0; j < n; j++) {
sum += (mul * c_odd);
if ((arr[j] & (1 << i)) > 0)
c_odd = (n - j - c_odd);
}
怪胎对怪胎的描述:
最佳解决方案:为了更好地理解,让我们假设元素的任何一点都由变量“ i”表示,变量“ sum”用于存储最终和。
这里的想法是,我们将尝试查找设置了第i个位的XOR值的数量。让我们假设,存在第i个位设置为“ Si”个子阵列。对于第i位,总和可以更新为总和+ =(2i * S)。
那么,问题是如何实现上述想法?
我们会将任务分为多个步骤。在每一步中,我们将尝试找到第i个位设置的XOR值的数量。 现在,我们将把每个步骤分为几个子步骤。在每个子步骤中,我们将尝试查找从索引“ j”(其中j在0到n – 1之间变化)和第X位设置为第i个位的子数组的数目。对于第i个位将被设置,子阵列的奇数个元素应在第i个位进行设置。 对于所有位,我们将在变量c_odd中存储从j = 0开始的子数组数量的计数,第i位设置为奇数个元素。然后,我们将遍历数组的所有元素,并在需要时更新c_odd的值。如果到达设置了第i位的元素“ j”,则将c_odd更新为c_odd =(n – j – c_odd)。这是因为,由于我们遇到了置位的问题,因此第i位设置为偶数个元素的子数组的数量将切换为第i位设置为奇数个元素的子数组的数量。
答案 0 :(得分:0)
这是一个很好的例子,表明对程序进行更仔细,更具描述性的阐述可以使它更易于理解和正确。
我们正在分别查看每个位。
让我们考虑第一个循环:它计算有多少个从索引0开始的子数组具有当前位集的奇数。 (似乎很清楚如何实现这一计数,但您可以随时询问。)
现在,在第二个循环中,我们可以使用此信息(并更新它)作为所有我们当前所在的子数组(而不是从索引0开始)稍后。假设初始计数为2,n = 10
,当前位设置在数组索引4和6的元素上。
现在,在每次迭代中,我们都在标记正在计数的子数组的左/下限。我们已经知道有2个子数组从索引0开始,到“某个地方以后”结束。但是,由于直到索引4才设置该位的实例,因此可以说对于低限1、2、3和4来说,此计数也成立:从子索引开始有2个子数组计数,然后在“某个地方结束”。 “
当到达索引4时,魔术发生了,我们需要更新计数。如果到现在为止,有2个子数组的起始位置为奇数i
,然后从“后”结束,则有10 - here - 2
个子数组的计数为{em> even {1}}设置从此处开始到“以后”结束(A [4..4],A [4..5],... A [4..9],但不包括A [4..4]和A [4..5]仅设置了一个i
位计数)。
当我们到达索引4时,我们重新计算子数组的数量,其中奇数i
设置为i
,从这里开始,到“某处稍后”结束通过设置位的实例,我们可以将以前具有偶数的所有子数组翻转到我们的新度量。