The Fenwick tree data structure requires a member function read. For a index idx, read must compute several indices idx[0], idx[1], idx[2], ..., idx[last]. Each idx[i] will be the value that results when you set the i least significant non-zero bits of idx to 0.
For example, if idx = 13 = ...00001101, then idx[1] = 13, idx[1] = 12 = ...00001100, and idx[2] = 8 = ...00001000.
If we assume, as most online sources on Fenwick trees do, that signed integers are represented using two's complement, idx[i] is easy to compute. In that case, idx[i+1] = idx[i] - (idx[i] & -idx[i]);. Justification for this line can be found here: Fenwick trees.
Prior to C++20, using bitwise & was implementation defined, but it appears C++20 now requires the use of two's complement. That leads to the following questions:
- Is it correct to say that, prior to C++20,
idx[i+1] = idx[i] - (idx[i] & -idx[i]);is "incorrect" code? - With C++20, is
idx[i+1] = idx[i] - (idx[i] & -idx[i]);now correct? - If the answer to (2) is "no", what is an efficient way to compute
idx[]? Ifidxis unsigned, can I just doidx[i+1] = idx[i] - (((~idx[i]) + 1) & idx[i])?