This question already has an answer here:
- meaning of (number) & (-number) 3 answers
For example:
int get(int i) {
int res = 0;
while (i) {
res = (res + tree[i]) % MOD;
i -= ( (i) & (-i) );
}
return res;
}
A tree update function:
void update(int i, int val) {
while (i <= m) {
tree[i] = (tree[i] + val) % MOD;
i += ( (i) & (-i) );
}
}
Can you please explain what they do in the code by using ( (i) & (-i) )
?
This two functions are a modified implementation of a Binary index tree (Fenwick tree) data structure.
Here is two pictures to supplement MikeCAT's answer showing how i variable updates for different values.
The "get" function:
For assume max value in of input in function is 15 for simplicity of representation.
A node with number t in on it represents tree[t] in the tree array.
If you call get function for i the returned value is sum of tree[i] plus sum of all tree array elements that their index in the array is a parent of i in the picture, except zero.
Here are some examples:
Numbers on the labels on nodes in the above picture, has the property that each node's parent is that node label minus the least significant one 1(explained very well on @MikeCAT answer) The "update" function:
For simplicity of picture, let assume that the max length of the tree array is 16.
The update function is little bit trickier.
It adds val to tree[i] and all tree elements that their index is parent of the node with label i in the picture.
In case anyone wanted a more general proof as well,
Assume
x
has the format a10k (meaning here, some bitstring a, followed by a 1, followed by k zeroes).-x
is (by definition) the same thing as~x + 1
, soSo we are left with only that single rightmost 1 that we assumed existed.
The assumption about the form of
x
leaves out the case thatx = 0
, in which case the result is obviously still zero.Let me assume that negative value is represented using two's complement. In this case,
-i
can be calculated as(~i)+1
(flip bits, then add 1).For example, let me consider
i = 44
. Then, in binary,As you see, the least bit that is 1 can be calculated using
(i) & (-i)
.