"x += x & (-x)" 是什么意思?
What does "x += x & (-x)" mean?
我发现很多人使用x += x & (-x)
、x -= x & (-x)
来解决区间树问题(在实现线段树、二叉索引树等数据结构时)。
你能解释一下这个等式是什么意思吗?
例如:
void update(int m, int x) {
m++;
while (m < N) {
t[m] = t[m] + x;
m += m & -m;
}
}
int query(int m) {
int result= 0;
m++;
while (m > 0) {
result = result + t[m];
m -= m & -m;
}
return result;
}
Note: This answer (like the method itself) assumes signed integers are represented in two's complement form.
表达式 x & -x
是一种快速的 - 但不可否认是神秘的 - 获取由 最低 集表示的值的方法x
中的位(当所有其他位都清除时)。这有时被称为位的 权重 ,并且在数值上等于 2 的位位置次方(其中最低有效位是位置 0
)。
该方法依赖于这样一个事实,即在二进制 (2s-comp) 中只能设置一个 单个位 x
和 -x
的表示 - 这实际上将是 x
.
中的 最不重要的 设置位
上有一些关于它如何工作的很好的解释,有很多例子
在您显示的 update
和 query
函数中,while
循环中 increase/decrease m
的数量因此是 weighted根据最低位设置位在(原)m
.
中的位置
随时要求进一步澄清 and/or 解释(但我不想 copy/paste 或解释太多我链接的讨论)。
因为@Adrian 已经就表达式的含义给出了一个很好的答案,我将用一个简单的例子来补充它,说明它是如何工作的。
让我们假设我们的 x
是一个 4 位数(为简单起见)1100b
。然后,
x
是 0000 1100b
(它的最低设置位在位置 2
(索引从左开始 0
)
-x
是 1111 0100b
作为 0000 1100b + 1111 0100b = 0b
-x & x
结果为 0100b
。唯一设置的位与 x
中最右边的位位于同一位置 - 在位置 2
。
在二叉索引树 (Fenwick_tree) 中,这些操作是更新和查询树。要查询树,您要通过重置元素最右边的设置位来查找元素的父级。要更新树,您需要不断向当前索引添加最低有效位以找到要更新的所有元素。
另一种解读方式可以如下:
设X
为一个数字。
那么X&-X
代表the greatest power of 2 that divides X
.
示例:
- 让
X = 10
,那么X&-X
就给2
.
- 让
X = 7
,那么X&-X
就给1
.
- 让
X = 4
,那么X&-X
就给4
.
我发现很多人使用x += x & (-x)
、x -= x & (-x)
来解决区间树问题(在实现线段树、二叉索引树等数据结构时)。
你能解释一下这个等式是什么意思吗?
例如:
void update(int m, int x) {
m++;
while (m < N) {
t[m] = t[m] + x;
m += m & -m;
}
}
int query(int m) {
int result= 0;
m++;
while (m > 0) {
result = result + t[m];
m -= m & -m;
}
return result;
}
Note: This answer (like the method itself) assumes signed integers are represented in two's complement form.
表达式 x & -x
是一种快速的 - 但不可否认是神秘的 - 获取由 最低 集表示的值的方法x
中的位(当所有其他位都清除时)。这有时被称为位的 权重 ,并且在数值上等于 2 的位位置次方(其中最低有效位是位置 0
)。
该方法依赖于这样一个事实,即在二进制 (2s-comp) 中只能设置一个 单个位 x
和 -x
的表示 - 这实际上将是 x
.
在您显示的 update
和 query
函数中,while
循环中 increase/decrease m
的数量因此是 weighted根据最低位设置位在(原)m
.
随时要求进一步澄清 and/or 解释(但我不想 copy/paste 或解释太多我链接的讨论)。
因为@Adrian 已经就表达式的含义给出了一个很好的答案,我将用一个简单的例子来补充它,说明它是如何工作的。
让我们假设我们的 x
是一个 4 位数(为简单起见)1100b
。然后,
x
是0000 1100b
(它的最低设置位在位置2
(索引从左开始0
)-x
是1111 0100b
作为0000 1100b + 1111 0100b = 0b
-x & x
结果为0100b
。唯一设置的位与x
中最右边的位位于同一位置 - 在位置2
。
在二叉索引树 (Fenwick_tree) 中,这些操作是更新和查询树。要查询树,您要通过重置元素最右边的设置位来查找元素的父级。要更新树,您需要不断向当前索引添加最低有效位以找到要更新的所有元素。
另一种解读方式可以如下:
设X
为一个数字。
那么X&-X
代表the greatest power of 2 that divides X
.
示例:
- 让
X = 10
,那么X&-X
就给2
. - 让
X = 7
,那么X&-X
就给1
. - 让
X = 4
,那么X&-X
就给4
.