"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.

中的 最不重要的 设置位

Quora.

上有一些关于它如何工作的很好的解释,有很多例子

在您显示的 updatequery 函数中,while 循环中 increase/decrease m 的数量因此是 weighted根据最低位设置位在(原)m.

中的位置

随时要求进一步澄清 and/or 解释(但我不想 copy/paste 或解释太多我链接的讨论)。

因为@Adrian 已经就表达式的含义给出了一个很好的答案,我将用一个简单的例子来补充它,说明它是如何工作的。

让我们假设我们的 x 是一个 4 位数(为简单起见)1100b。然后,

  1. x0000 1100b(它的最低设置位在位置 2(索引从左开始 0
  2. -x1111 0100b 作为 0000 1100b + 1111 0100b = 0b
  3. -x & x 结果为 0100b。唯一设置的位与 x 中最右边的位位于同一位置 - 在位置 2

在二叉索引树 (Fenwick_tree) 中,这些操作是更新和查询树。要查询树,您要通过重置元素最右边的设置位来查找元素的父级。要更新树,您需要不断向当前索引添加最低有效位以找到要更新的所有元素。

另一种解读方式可以如下:

X为一个数字。 那么X&-X代表the greatest power of 2 that divides X.

示例:

  1. X = 10,那么X&-X就给2.
  2. X = 7,那么X&-X就给1.
  3. X = 4,那么X&-X就给4.